【问题标题】:WM_CLOSE message and application freezeWM_CLOSE 消息和应用程序冻结
【发布时间】: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 案例代码中的礼物才会使应用程序冻结。

标签: c++ windows visual-studio


【解决方案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 - 那么您有责任为响应该消息执行某事

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 2019-11-04
    • 2015-05-09
    • 2013-09-26
    • 2014-09-29
    相关资源
    最近更新 更多