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.

+3


source to share


1 answer


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.

+8


source







All Articles