0

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?

The Light Spark
  • 504
  • 4
  • 19
  • 2
    Where's this message loop actually running? At your main window instance? – πάντα ῥεῖ Sep 28 '14 at 14:41
  • That does not seem to be a correct message loop. Please post a [MCVE](http://stackoverflow.com/help/mcve). `GetMessage` returns `0` on `WM_QUIT` so your message loop might not be evaluated at all. – Csq Sep 28 '14 at 14:41
  • 1
    Normally, you would handle the message inside the window procedure, not the message loop. This has the advantage of actually being relevant to the window they're sent to. – chris Sep 28 '14 at 14:43
  • @πάνταῥεῖ | my message loop runs in another object's instance, but that same object owns the window proc where the message is read. – The Light Spark Sep 28 '14 at 14:43
  • @TheLightSpark has that been registered as the window's callback function? – Marco A. Sep 28 '14 at 14:48
  • @MarcoA. yes, very well. – The Light Spark Sep 28 '14 at 14:51
  • At this point please post the code with a MCVE – Marco A. Sep 28 '14 at 14:52
  • @Marco is that okay what i just edited? – The Light Spark Sep 28 '14 at 14:54
  • Probably some context would be better :) – Marco A. Sep 28 '14 at 14:54
  • just a sidenote : if you actually write your own messageloop you're doing something horribly wrong. Using the low-level API within windows is both unnecessary and very error-prone, you're currently experiencing the results of this mistake. – specializt Sep 28 '14 at 14:59
  • It's odd that you posted fake code. There is no `PeakMessage`. It's `PeekMessage`. Your message loop is a busy loop. I don't know why you rejected `GetMessage`. Synchronous messages like `WM_DESTROY` and `WM_CLOSE` are dispatched by `PeekMessage`, `GetMessage` etc. `PeekMessage`, `GetMessage` return async messages. – David Heffernan Sep 28 '14 at 19:44

1 Answers1

4

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Can I receive `WM_CLOSE` in subclass proc? I just can't seem to get it. – Hitesh Kumar Saini Oct 14 '22 at 03:37
  • 1
    Yes, `WM_CLOSE` can be seen by a subclassed window procedure. ALL messages posted or sent to a window will go through its window procedure. If you are not seeing the message, then you are doing something wrong in your code. – Remy Lebeau Oct 14 '22 at 17:23