Getting several WM_PAINT message with one dispatch

378 Views Asked by At

I'm getting several WM_PAINT messages/events in the message handler for my window while I resize it, even though I only translate+dispatch a single message.

Is this normal? Why is this happening? (I was expecting to get one WM_PAINT message per dispatch, and never more than that)

Window loop:

while (true) // only for the example
{
    std::cout << "Checking events\n";

    MSG winEvent = {};
    while (PeekMessage(&winEvent, NULL, 0, 0, PM_REMOVE))
    {
        std::cout << "ev\n";
        TranslateMessage(&winEvent);
        DispatchMessage(&winEvent);
    }
}

Message handler function:

LRESULT CALLBACK windowEvent(HWND _hwnd, UINT _uMsg, WPARAM _wParam, LPARAM _lParam)
{
    switch (_uMsg)
    {
    // extra cases removed for the example
    case WM_PAINT:
        std::cout << "PAINT EVENT\n";
        return DefWindowProc(_hwnd, _uMsg, _wParam, _lParam);
    }

    return DefWindowProc(_hwnd, _uMsg, _wParam, _lParam);
}

Console output:

  • prior to clicking, many "checking events" and "ev" messages appear
  • when first clicking on the border of the window, "ev" appears
  • while holding left click, no messages appear
  • when holding and dragging to make the window bigger, more "PAINT EVENT" messages appear
Checking events
ev
PAINT EVENT
PAINT EVENT
PAINT EVENT
PAINT EVENT
PAINT EVENT
PAINT EVENT
PAINT EVENT
PAINT EVENT
1

There are 1 best solutions below

2
On BEST ANSWER

The answer is simple:

Starting the resize enters into a nested message-loop, one you didn't instrument.

Thus, you get posted messages delivered which the outer loop, which you wrote yourself, never knew about.

That the WM_PAINT message is generally generated for an empty message-queue if there was any invalidation, instead of posted, doesn't change anything relevant.