2

Having such a simple Win application:

bool continueRunning = true;
...
int APIENTRY wWinMain(...) {
        while (continueRunning) {

            PeekMessage(&msg, 0, 0, 0, PM_REMOVE);

            TranslateMessage(&msg);
            DispatchMessage(&msg);

            if (WM_DESTROY == msg.message) {
                OutputDebugString(L"--- WM_DESTROY (WinMain) ---\n");
            }   
        }
}

...

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    switch (message) {      

        case WM_DESTROY:
            OutputDebugString(L"--- WM_DESTROY (WndProc) ---\n");
            continueRunning = false;
            break;

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

I got --- WM_DESTROY (WndProc) --- message but not --- WM_DESTROY (WinMain) ---.

How does the message WM_DESTROY is passed to the app since the PeekMessage doesn't get it?

Daros911
  • 435
  • 5
  • 14
  • 3
    `WM_DESTROY` is *sent* and goes directly to the window proc. See the first paragraph in the [docs](https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-destroy). – dxiv Jan 04 '21 at 17:34
  • Ok but HOW the app greps such a message since there is no `PeekMessage` - like function in the window proc? – Daros911 Jan 04 '21 at 17:37
  • `WM_DESTROY` never gets into the message queue. It is a sent message and gets passed to the window proc directly. – dxiv Jan 04 '21 at 17:43
  • But i don't have the explicit `SendMessage` call in my code. Is it just send implicitelly/defaultly/automatically by the system when i click the 'X' button? – Daros911 Jan 04 '21 at 17:50
  • 1
    It is sent by Windows "*when a window is being destroyed*", quoting from the same docs. See more at [Why can't I get a WM_DESTROY or WM_CLOSE message outside a window procedure?](https://stackoverflow.com/questions/26085976/why-cant-i-get-a-wm-destroy-or-wm-close-message-outside-a-window-procedure) and [WndProc calling mechanism (WinAPI)](https://stackoverflow.com/questions/35248676/wndproc-calling-mechanism-winapi). – dxiv Jan 04 '21 at 17:53
  • So if it's sent automatically by Windows what's the case/purpose in sending it explicitelly by calling the `SendMessage`? – Daros911 Jan 04 '21 at 17:57
  • "*what's the case/purpose in sending it explicitelly*" Where did you see that being done? – dxiv Jan 04 '21 at 17:58
  • [There](https://stackoverflow.com/questions/18827617/how-to-intercept-a-message-wm-quit-wm-destroy-wm-close-winapi/18828222) is an _Hans_ _Passant_ answer: "That will never be WM_CLOSE or WM_DESTROY, those messages are sent with SendMessage()" – Daros911 Jan 04 '21 at 18:02
  • "*those messages are sent*" By Windows. – dxiv Jan 04 '21 at 18:03
  • Sorry for being so meticulous but there is "those messages are sent with SendMessage" NOT "those messages are sent by Windows" in the cited answer... – Daros911 Jan 04 '21 at 18:11
  • The answer is not (and could not possibly be) quoting the entire Win32 reference. From the [`DestroyWindow`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-destroywindow) documentation: "*Destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu ...*". – dxiv Jan 04 '21 at 18:13
  • So the _Hans_ _Passant_ answer in [this thread](https://stackoverflow.com/questions/18827617/how-to-intercept-a-message-wm-quit-wm-destroy-wm-close-winapi/18828222) is incorrect saying "those messages are sent with SendMessage"? – Daros911 Jan 04 '21 at 18:20
  • No, that is entirely correct. `DestroyWindow` sends the `WM_DESTROY` message using `SendMessage`. – dxiv Jan 04 '21 at 18:26
  • Does this answer your question? [Why can't I get a WM\_DESTROY or WM\_CLOSE message outside a window procedure?](https://stackoverflow.com/questions/26085976/why-cant-i-get-a-wm-destroy-or-wm-close-message-outside-a-window-procedure) – Raymond Chen Jan 04 '21 at 18:26
  • @Raymond Chen Yes it's helpful bu the answers to my own question are also valuable. – Daros911 Jan 04 '21 at 18:32
  • @Daros911 you seem to have a fundamental lack of understanding the difference between POSTED (queued) messages and SENT (non-queued) messages. Have you read [Messages and Message Queues](https://learn.microsoft.com/en-us/windows/win32/winmsg/messages-and-message-queues) yet? In particular, at [Message Routing](https://learn.microsoft.com/en-us/windows/win32/winmsg/about-messages-and-message-queues#message-routing) of Queued vs Nonqueued Messages. – Remy Lebeau Jan 04 '21 at 18:48

1 Answers1

3

PeekMessage (or GetMessage) dispatches sent messages (from other threads) on its own without returning them. Only posted messages are returned by it. If a message is sent by the same thread, it does not even go via PeekMessages, it is effectively a direct window procedure call. WM_DESTROY is sent.

By the way, avoid not passing system messages to DefWindowProc, including WM_DESTROY.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
  • Sorry, but a don't get it. What do You mean by "sent messages by itself" and "only posted messages "? – Daros911 Jan 04 '21 at 17:51
  • I've edited my answer, hope it is now more clear – Alex Guteniev Jan 04 '21 at 17:53
  • OK thx. for clarification. "it is effectively a direct window procedure call" that's mean that the system implicitelly calls WndProc with message param == WM_DESTROY when i close the window (e.g. click the `X` button)? – Daros911 Jan 04 '21 at 18:08
  • Clicking the `X` button sets off a chain reaction, and one of the steps (but not the first step) is the system sending the `WM_DESTROY` message to the window. – Raymond Chen Jan 04 '21 at 18:27