Search code examples
c++winapimessage-loop

Why can't I get a WM_DESTROY or WM_CLOSE message outside a window procedure?


I wanted to read out messages in my message loop right before I dispatch them to my window procedure. Most messages I tried reading like this were read correctly, but when I close the window, a WM_CLOSE or WM_DESTROY message could not be read as it seems as if they were never received. Here's what i do:

void Framework::Run(){
while(running){

    MSG msg;
    while(PeakMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        switch(msg.message){
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            case WM_QUIT:
                running = false;
                break;
        //...other cases...
        }
        DispatchMessage(&msg);
    }
//...
}
}

I put a breakpoint at the first case, but even when I close the window (by clicking the 'X') the breakpoint is never hit. Though, when I check for WM_DESTROY in the window procedure, it gets read and every thing goes fine. Why not outside it?

Are such messages sent directly to the window proc? How?


Solution

  • A message loop only sees messages that are posted to the calling thread's message queue. Not all messages go through the message queue. WM_DESTROY is one such message. What you should be doing instead is handling the messages in the window procedure so you see every message that the window receives, whether the message went through the message queue or not.

    If you need to look at messages for a window you are not creating yourself, or for a standard window that has a system-provided window procedure, you can subclass the window using SetWindowLongPtr(GWLP_WNDPROC) or SetWindowSubclass(). See Subclassing Controls for more details.