WM_CLOSE 消息和应用程序冻结

Posted

技术标签:

【中文标题】WM_CLOSE 消息和应用程序冻结【英文标题】:WM_CLOSE message and application freeze 【发布时间】:2021-01-03 17:10:25 【问题描述】:

拥有如此超级简单的Win app:

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)     
                
    ...

    MyRegisterClass(hInstance);     

    // Perform application initialization:
    if (!InitInstance(hInstance, nCmdShow)) 
        return FALSE;
           

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GL1WIN));

    MSG msg;        

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0)) 

        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
            TranslateMessage(&msg);
            DispatchMessage(&msg);

               
    

    return (int)msg.wParam;
  

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)                

    switch (message) 

        case WM_COMMAND: 
            int wmId = LOWORD(wParam);
            // Parse the menu selections:
            switch (wmId) 
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            
        
        break;          

        case WM_CLOSE:              
            break;

        case WM_DESTROY:                
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    

    return 0;

   

WM_CLOSE 案例被禁用(注释掉)时,一切正常 - 当我单击 X 按钮时,窗口关闭,但当 WM_CLOSE 案例像上面的代码一样启用时,应用程序似乎冻结了 -单击X 按钮时没有反应,我必须从task manager 中杀死它。

【问题讨论】:

当消息循环收到WM_CLOSE 时,您认为您的代码会做什么?您直接转到return 0; 声明。或者,也许我应该问:你想要你的代码做什么?如果您不处理该消息,则应返回一个非零值。 WM_CLOSE 情况下的代码是什么无关紧要。可能只有OutputDebugString(L"WM_CLOSE "); 指令。我的问题是,正如我已经写过的那样,只有 WM_CLOSE 案例代码中的礼物才会使应用程序冻结。 【参考方案1】:

在 WM_CLOSE 上,窗口通常应该用DestroyWindow 销毁,例如:

 case WM_CLOSE:   
            DestroyWindow(hWnd);
            break;

在你的情况下,你只是返回而不对那个窗口做任何事情,所以它很简单'冻结'。

【讨论】:

所以我必须要么调用 WM_CLOSE 中的DestroyWindow 方法,要么直接删除它? 如果您想销毁窗口以响应WM_CLOSE 消息,那么您应该在该消息的处理程序中调用DestroyWindow,或者将消息传递给DefWindowProc,它将调用DestroyWindow 给你。有很多方法可以安排代码以实现其中一种结果。 是的,你可以忽略 WM_CLOSE 并且什么也不会发生,或者你用它做点什么,比如 DestroyWindow【参考方案2】:

如果没有WM_CLOSE 情况,消息将传递给DefWindowProcDefWindowProc 通过销毁窗口对其作出反应。对于WM_CLOSE 案例,您处理消息而不将其传递给DefWindowProc - 那么您有责任为响应该消息执行某事

【讨论】:

以上是关于WM_CLOSE 消息和应用程序冻结的主要内容,如果未能解决你的问题,请参考以下文章

使用findwindow找到隐藏窗口使用sendmessage发送wm_close消息,无法关闭。

我覆盖了 WM_CLOSE,现在如何从应用程序中出来

VC向浏览器(IE,Firefox)发送鼠标单击消息

当模式对话框处于活动状态时,检测主应用程序窗口上的 WM_CLOSE 事件?

滚动时水平集合视图冻结

C++ COM、Direct2D、Win32 和 WM_CLOSE