Win32消息循环:使用GetMessage(& msg,NULL,0,0)关闭窗口后退出?

时间:2011-02-04 00:18:15

标签: c winapi window message-loop

如果我在下面有以下代码,如何检测窗口何时关闭,我可以退出? r似乎永远不会得到值 -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);
}

2 个答案:

答案 0 :(得分:3)

等待r = -1并不是您检测到窗口已关闭的方式。返回值-1不是正常情况:它表示消息循环中发生了错误。

来自documentation

  

返回值

     

输入: BOOL

     

如果函数检索WM_QUIT以外的消息,则返回值为非零值。

     

如果函数检索WM_QUIT消息,则返回值为零。

     

如果有错误,则返回值为-1。例如,如果hWnd是无效的窗口句柄或lpMsg是无效指针,则函数将失败。要获取扩展错误信息,请致电GetLastError

GetMessage从队列中检索WM_QUIT消息时,它将返回值0,您应该结束循环。

如果您只是想知道窗口何时关闭,您可能想要处理WM_CLOSEWM_DESTROY消息。有关这些消息的讨论,请参阅此问题的答案:What is the difference between WM_QUIT, WM_CLOSE, and WM_DESTROY in a windows program?

答案 1 :(得分:0)

我找到了一个解决方案: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可以检查窗口(肯定)。