窗口在Win32应用程序将无法正常关闭
原来的问题:
我不能不管我的窗口过程函数创建能够检测WM_CLOSE
消息,并呼吁PostQuitMessage
并让Windows后立即关闭窗口继续使用DefWindowProc
处理窗口消息。窗口在Win32应用程序将无法正常关闭
但是,通过拖动标题栏移动窗口后,它似乎能够正常关闭。
为我的窗口过程函数的代码如下:
LRESULT CALLBACK OnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_QUIT:
{
printf("WM_QUIT\n");
break;
}
case WM_CLOSE:
{
printf("WM_CLOSE\n");
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(handle, message, wParam, lParam);
}
因此,除了发送WM_MOVE
消息给我的窗口或在WM_CLOSE
情况下块使用exit(0)
,我怎么能保证我的窗口可以创建后立即关闭?
新问题:
传递NULL
到GetMessageW
的hWnd
参数,而不是我的窗口句柄后,窗口关闭现在正确回答,因此我刚才的问题。
因此,为什么GetMessageW
功能以前没有,唯一的窗口提供手柄检索WM_QUIT
消息,而不是使用NULL
为hWnd
参数?
一个正确写消息循环,永远不会分派WM_QUIT
消息到窗口过程时,当它接收到WM_QUIT
消息GetMessage()
返回0,它会简单地打破循环:
如果该函数检索WM_QUIT以外的消息,则返回值不为零。
如果该函数检索WM_QUIT消息,则返回值为零。
如果出现错误,则返回值为-1。例如,如果hWnd是一个无效的窗口句柄或者lpMsg是一个无效指针,则该函数失败。要获得扩展的错误信息,请调用GetLastError。
针对WM_CLOSE
,你应该叫DestroyWindow()
,而不是直接PostQuitMessage()
(的DefWindowProc(WM_CLOSE)
默认行为是调用DestroyWindow()
你)。你需要一个WM_DESTROY
处理那么应该调用PostQuitMessage()
:
LRESULT CALLBACK OnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
{
printf("WM_CLOSE\n");
DestroyWindow(handle);
return 0;
}
case WM_DESTROY:
{
printf("WM_DESTROY\n");
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(handle, message, wParam, lParam);
}
这是记录在MSDN:
下面是从页流程图:
至于GetMessage()
问题,如果您阅读对于GetMessage()
和PostQuitMessage()
的文档更加仔细,您将会看到,发送的WM_QUIT
消息不是窗口消息。传递非NULL HWND
至GetMessage()
只会检索PostMessage()
和SendMessage()
中用于该特定的邮件HWND
。 GetMessage()
将忽略不旨在为HWND
,其包括螺纹从PostThreadMessage()
PostQuitMessage()
和消息的任何消息。传递一个NULL HWND
到GetMessage()
允许它返回任何未决的消息,包括WM_QUIT
。
这是危险的事,顺便说一句:The dangers of filtering window messages
好吧,虽然我现在明白我的错误,但这很令人尴尬。 – benardier
未测试,调用'PostQuitMessage(0);'和不调用'DefWindowProc'用于消息'WM_QUIT'可能不太好。 – MikeCAT
它可能对您有用。 https://msdn.microsoft.com/en-us/library/windows/desktop/ff381396%28v=vs.85%29.aspx并且在'printf(“WM_QUIT \ n”);'之后,没有'打破;'。可以吗? –
除非出现严重错误,否则'WM_QUIT'将永远不会传递到您的WndProc。 –