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
情况,消息将传递给DefWindowProc
,DefWindowProc
通过销毁窗口对其作出反应。对于WM_CLOSE
案例,您处理消息而不将其传递给DefWindowProc
- 那么您有责任为响应该消息执行某事。
【讨论】:
以上是关于WM_CLOSE 消息和应用程序冻结的主要内容,如果未能解决你的问题,请参考以下文章
使用findwindow找到隐藏窗口使用sendmessage发送wm_close消息,无法关闭。