Steve
Steve

Reputation: 731

Does DestroyWindow() remove the messages for the window from the message queue?

The DestroyWindow() documentation says the following:

The function also destroys the window's menu, flushes the thread message queue,

Does "flushes the thread message queue" means that it will remove the messages from the message queue for the window that I want to destroy only?

Upvotes: 5

Views: 1087

Answers (1)

Jonathan Potter
Jonathan Potter

Reputation: 37192

Although the docs are not explicit on this, it does behave as you suggest. Messages posted to the destroyed window are flushed and those for other windows (or posted to the thread) remain in the thread's queue.

The following sample program demonstrates this - if your suggestion is true, no asserts should fire (and in my tests, they don't).

As @HarryJohnston points out in the comments, destroying one window own by a thread does not destroy any other windows the thread owns (except for children and owned windows of the destroyed window), and so it could be quite problematic if their posted messages were removed, effectively for no reason.

#include <windows.h>
#include <assert.h>  

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    assert(message != WM_APP + 1);
    return DefWindowProc(hWnd, message, wParam, lParam);
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEXW wcex{};
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;
    wcex.lpszClassName = L"msgflushtest";
    assert(RegisterClassExW(&wcex));

    HWND hWnd = CreateWindowEx(0, L"msgflushtest", nullptr, WS_POPUP, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
        HWND_DESKTOP, nullptr, hInstance, nullptr);
    assert(hWnd);

    assert(PostMessage(hWnd, WM_APP + 1, 0, 0)); // should be flushed
    assert(PostThreadMessage(GetCurrentThreadId(), WM_APP + 2, 0, 0)); // should not be flushed

    DestroyWindow(hWnd);

    MSG msg;
    assert(!PeekMessage(&msg, nullptr, WM_APP + 1, WM_APP + 1, PM_REMOVE));
    assert(PeekMessage(&msg, nullptr, WM_APP + 2, WM_APP + 2, PM_REMOVE));

    return 0;
}

Upvotes: 5

Related Questions