Does PostQuitMessage () go into WM_DESTROY or WM_CLOSE?
I am trying to create a very basic window using the Win32 API and I did it a long time ago.
I think my message loop is fine, but when I close the open window, the application is still running. It looks like the message loop never gets the message WM_QUIT
. However, I call PostQuitMessage
and the message box confirms that I called it.
What's wrong with this minimalist code?
#include <Windows.h>
LRESULT CALLBACK window_proc(HWND hwnd, UINT msg,
WPARAM w_param, LPARAM l_param) {
switch (msg) {
case WM_DESTROY:
MessageBox(NULL, L"destroy", L"info", MB_OK);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, w_param, l_param);
}
return 0;
}
int CALLBACK WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance,
LPSTR cmd_line, int n_cmd_show) {
WNDCLASS wnd_class;
HWND hwnd;
MSG msg;
BOOL ret;
wnd_class.cbClsExtra = 0;
wnd_class.cbWndExtra = 0;
wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd_class.hInstance = h_instance;
wnd_class.lpfnWndProc = window_proc;
wnd_class.lpszClassName = L"MyWindowClass";
wnd_class.lpszMenuName = NULL;
wnd_class.style = 0;
if (!RegisterClass(&wnd_class)) {
MessageBox(NULL, L"cannot register window class",
L"error", MB_OK | MB_ICONERROR);
}
hwnd = CreateWindow(
L"MyWindowClass",
L"",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
h_instance,
NULL
);
while ((ret = GetMessage(&msg, hwnd, 0, 0)) != 0) {
if (ret == -1) {
MessageBox(NULL, L"error", L"", MB_OK);
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
MessageBox(NULL, L"quitting now", L"info", MB_OK);
return msg.wParam;
}
The document GetMessage
states that the function returns 0 when it reads a message WM_QUIT
. Called Howcome PostQuitMessage
and GetMessage
never returns 0?
Thank you Win32 guru.
source to share
Its your cycle GetMessage()
.
You pass your window handle to this loop, thereby filtering out all messages in the application thread and getting only messages in that window.
Change this:
while ((ret = GetMessage(&msg, hwnd, 0, 0)) != 0)
// Note window handle =========^
For this:
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
// Note no handle =============^
Your application thread should now be controlled by your loop GetMessage()
.
Why: GetMessage()
Calls can be configured to monitor a specific window message queue. The WM_QUIT application is not submitted to the window descriptor queue; it is sent to the thread's message queue, which can only take messages off the queue with GetMessage()
(maybe PeekMessage()
, but too long for me to remember) without a target window handle for a specific control.
source to share