Win32消息循环:使用GetMessage(&msg,NULL,0,0)关闭窗口后退出?
如果我在下面有以下代码,如何检测窗口何时关闭,以便我可以退出? 似乎永远不会得到值-1
0
,我需要处理整个线程的消息,而不仅仅是当前窗口。
HWND hWnd = CreateWindowExW(0, L"Edit", L"My Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, NULL, NULL); ShowWindow(hWnd, SW_SHOWDEFAULT); MSG msg; BOOL r; while ((r = GetMessageW(&msg, NULL, 0, 0)) != 0) { if (r == -1) { break; } TranslateMessage(&msg); DispatchMessageW(&msg); }
等待r = -1
不是您检测到窗口已关闭的方式。 返回值-1不是正常情况:它表示消息循环中发生了错误。
从文档 :
回报价值
类型:
BOOL
如果函数检索
WM_QUIT
以外的消息,则返回值为非零。如果函数检索
WM_QUIT
消息,则返回值为零。如果有错误,则返回值为-1。 例如,如果hWnd是无效的窗口句柄或
lpMsg
是无效指针,则函数将失败。 要获取扩展错误信息,请调用GetLastError
。
当GetMessage
从队列中检索WM_QUIT
消息时,它将返回值0,您应该结束循环。
如果您只想知道窗口何时关闭,您可能想要处理WM_CLOSE
或WM_DESTROY
消息。 有关这些消息的讨论,请参阅此问题的答案: Windows程序中WM_QUIT,WM_CLOSE和WM_DESTROY之间的区别是什么?
我找到了一个解决方案: WM_NULL
。
消息循环可以独立于WndProc
自行处理问题:
// written in C# MSG msg = new MSG(); while (GetMessage(out msg, window, 0, 0)) { if ((msg.message == WM_NULL) && !IsWindow(window)) break; TranslateMessage(ref msg); DispatchMessage(ref msg); } Console.WriteLine("yeah, out of loop ^^");
从我的观察:当窗口被销毁时, GetMessage
无需暂停(第一个提示)检索WM_NULL
消息, IsWindow
可以检查窗口(肯定)。