What is the difference between WM_QUIT, WM_CLOSE, and WM_DESTROY in a windows program?

52,246

Solution 1

They are totally different.

WM_CLOSE is sent to the window when it is being closed - when its "X" button is clicked, or "Close" is chosen from the window's menu, or Alt-F4 is pressed while the window has focus, etc. If you catch this message, this is your decision how to treat it - ignore it, or really close the window. By default, WM_CLOSE passed to DefWindowProc() causes the window to be destroyed.

WM_DESTROY is sent to the window when it starts to be destroyed. In this stage, in opposition to WM_CLOSE, you cannot stop the process, you can only make any necessary cleanup. When you catch WM_DESTROY, none of its child windows have been destroyed yet.

WM_NCDESTROY is sent to the window when it is finishing being destroyed. All of its child windows have been destroyed by this time.

WM_QUIT is not related to any window (the hwnd got from GetMessage() is NULL, and no window procedure is called). This message indicates that the message loop should be stopped and the application should exit. When GetMessage() reads WM_QUIT, it returns 0 to indicate that. Take a look at a typical message loop snippet - the loop is continued while GetMessage() returns non-zero.

WM_QUIT can be sent by the PostQuitMessage() function. This function is usually called when the main window receives WM_DESTROY (see a typical window procedure snippet).

Solution 2

First of all, the WM_CLOSE and WM_DESTROY messages are associated with particular windows whereas the WM_QUIT message is applicable to the whole application (well thread) and the message is never received through a window procedure (WndProc routine), but only through the GetMessage or PeekMessage functions.

In your WndProc routine the DefWindowProc function takes care of the default behavoir of these messages. The WM_CLOSE messages requests that the application should close and the default behavoir for this is to call the DestroyWindow function. Its when this DestroyWindow function is called that the WM_DESTROY message is sent. Notice that the WM_CLOSE is only a message requesting that you close (like WM_QUIT) - you don't actually have to exit/quit. But the WM_DESTROY message tells you that your window IS being closed and destroyed so you must cleanup any resources, handles etc.

Solution 3

Just so it doesn't get lost in the comments... don't forget about WM_CANCEL. When you click the close (x) button on an MFC dialog, it will certainly send WM_CLOSE. The default OnClose() function will then call the default (base class) OnCancel() function.

However, if you simply type the ESC key, this will lead to the closure of the dialog, but (as far as I can tell) without generating the WM_CLOSE event - it goes directly to the WM_CANCEL/OnCancel() mechanism.

I hereby invite the community to elaborate on this... or edit that elaboration into the accepted answer.

Solution 4

At first let's discuss WM_QUIT - the difference from another messages that this is not associated with window. It is used by application. For example this can be handled by non-visible standalone OLE server (.exe, but not in-proc as .dll)

WM_CLOSE - per msdn: "An application can prompt the user for confirmation, prior to destroying a window" - it is used as notification about intention to close (you can reject this intention).

WM_DESTROY - is a fact that window is closing and all resources must(!) be deallocated.

Solution 5

I know this is old, but just trying to provide a clearer answer for anyone.

// What causes each message?
WM_CLOSE:       // Pressed Close Button (X) / Alt+F4 / "Close" in context menu
WM_DESTROY:     // Called DestroyWindow(hwnd)
WM_QUIT:        // Called PostQuitMessage(exit)

// What do they do by default?
case WM_CLOSE: DestroyWindow(hwnd); return 0; // pressed close? destroy window.
case WM_DESTROY: PostQuitMessage(0); return 0; // destroyed window? quit message loop.
// WM_QUIT isn't associated with a window, so isn't sent to the window procedure

So WM_CLOSE is just so we can request to destroy the window. However you might want it to show a popup in your game asking if you're sure. (and if you want to save first)

And WM_DESTROY doesn't actually post the quit message by default, since you could have multiple windows. That's just the usual event we quit after. You could have WM_CLOSE call PostQuitMessage(exit) and destroy your window(s) after the message loop if you wanted.

If you wanted a custom close button in your game, it should do what WM_CLOSE does.

Also there is the function CloseWindow(hwnd), however it simply minimizes the window.

Hope this helps anyone.

Share:
52,246

Related videos on Youtube

Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I was wondering what the difference between the WM_QUIT, WM_CLOSE, and WM_DESTROY messages in a windows program, essentially: when are they sent, and do they have any automatic effects besides what's defined by the program?

    • bvs
      bvs almost 6 years
      very good quest
  • Dewfy
    Dewfy almost 14 years
    @atzz yes, you are right. Talking in general this message notifies event loop to stop handling at all, regardless application-wide or standalone thread.
  • Basj
    Basj almost 7 years
    @ad88 would be great to add what happens when User Logout / WM_ENDSESSION arrives. Does this automatically trigger WM_CLOSE / QUIT / DESTROY ?
  • 0xC0000022L
    0xC0000022L over 6 years
    Not to the whole application, but to a particular message loop. Each thread may have its own message loop, so an application can have several message loops.
  • Remy Lebeau
    Remy Lebeau over 3 years
    When a session ends, any remaining windows that still exist are simply destroyed by the OS, there are no WM_CLOSE/WM_DESTROY messages sent to them. They have their last chance to cleanup by handling WM_(QUERY)ENDSESSION. After all, all bets are off. See Windows doesn't close windows when a user logs off; that's your call