Win32:关闭窗口

当用户关闭窗口时,该操作会触发一系列窗口消息。

用户可以通过单击“ 关闭 ”按钮或使用 Alt+F4 等键盘快捷方式来关闭应用程序窗口。 任何这些操作都会导致窗口接收 WM_CLOSE 消息。

WM_CLOSE消息

WM_CLOSE消息使你有机会在关闭窗口之前提示用户。 如果确实想要关闭窗口,请调用 DestroyWindow 函数。 否则,只需从 WM_CLOSE 消息中返回零,操作系统将忽略该消息,不会销毁窗口。

下面是程序如何处理 WM_CLOSE的示例。

    case WM_CLOSE:
        if (MessageBox(hwnd, TEXT("确定退出程序?"), TEXT("My application"), MB_OKCANCEL) == IDOK)
        {
            DestroyWindow(hwnd);
        }
        //若选择取消,则不进行操作
        return 0;

在此示例中, MessageBox 函数显示包含 “确定” 和“ 取消 ”按钮的模式对话框。 如果用户单击“ 确定”,程序将调用 DestroyWindow。 否则,如果用户单击“ 取消”,则会跳过对 DestroyWindow 的调用,并且窗口保持打开状态。 在任一情况下,都返回零以指示你处理了消息。效果如下:

Windows 应用程序处理 WM_CLOSE 消息时,如果不对其进行显式处理,DefWindowProc 函数会默认调用 DestroyWindow 来关闭窗口。这意味着,如果忽略 switch 语句中的WM_CLOSE消息,则默认情况下会销毁窗口。当窗口即将被销毁时,它会收到 WM_DESTROY 消息。 此消息在从屏幕中删除窗口之后,但在销毁发生之前, (特别是在) 销毁任何子窗口之前发送。在main应用程序窗口中,通常会通过调用 PostQuitMessage 来响应WM_DESTROY

case WM_DESTROY:
    PostQuitMessage(0);
    return 0;

我们在 “窗口消息 ”部分看到, PostQuitMessageWM_QUIT 消息置于消息队列中,导致消息循环结束。

下面是一个流程图,其中显示了处理 WM_CLOSEWM_DESTROY 消息的典型方法:

最后代码
#include <windows.h>
#include <stdio.h>
​
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_DESTROY:
        PostQuitMessage(0);  // 发送退出消息
        return 0;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
​
        // All painting occurs here, between BeginPaint and EndPaint.
​
        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 4));
        // 绘制文本
        TextOut(hdc, 10, 10,TEXT("Hello, World!"), 13);
​
        EndPaint(hwnd, &ps);
        return 0;
    }
    case WM_CLOSE:
        if (MessageBox(hwnd, TEXT("确定退出程序?"), TEXT("My application"), MB_OKCANCEL) == IDOK)
        {
            DestroyWindow(hwnd);
        }
        // Else: User canceled. Do nothing.
        return 0;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);  // 默认消息处理
    }
}
​
int WINAPI wWinMain(
    HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    PWSTR pCmdLine, 
    int nCmdShow) 
{
    //注册窗口类
    const wchar_t CLASS_NAME[] = L"WolvenChan's Window Class";
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    RegisterClass(&wc); 
​
    //创建窗口
    HWND hwnd = CreateWindowEx(
        0,
        CLASS_NAME,
        TEXT("Hello Wolven"),
        WS_OVERLAPPEDWINDOW,
        //坐标、窗口长、高
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
        );
​
    if (hwnd == NULL) {
        MessageBox(NULL, L"Failed to create window!", L"Error", MB_ICONERROR);
        return 0;
    }   
​
    ShowWindow(hwnd, nCmdShow);
    
    //消息循环
    MSG msg = { 0 };
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);  // 翻译消息
        DispatchMessage(&msg);   // 分发消息
    }
​
    return (int)msg.wParam;
​
    return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值