If I have the following code below, how do I detect when the window has been closed, so I can quit? r
never seems to get the value -1
0
, and I need to process messages for the entire thread, not just the current window.
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);
}
Waiting for r = -1
is not the way you detect that your window has closed. A return value of -1 is not a normal condition: it indicates that an error has occurred in the message loop.
From the documentation:
Return Value
Type: BOOL
If the function retrieves a message other than WM_QUIT
, the return value is nonzero.
If the function retrieves the WM_QUIT
message, the return value is zero.
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg
is an invalid pointer. To get extended error information, call GetLastError
.
When GetMessage
retrieves a WM_QUIT
message from the queue, it will return a value of 0, and you should end the loop.
If you just want to know when the window has closed, you probably want to handle either the WM_CLOSE
or WM_DESTROY
messages. For a discussion of these messages, see the answers to this question: What is the difference between WM_QUIT, WM_CLOSE, and WM_DESTROY in a windows program?
I found a solution for this: WM_NULL
.
The message loop can handle the matter on its own independently of 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 ^^");
From my observation: When window is destroyed GetMessage
retrieves WM_NULL
messages without pause (1st hint) and IsWindow
can check the window (affirmation).