简体   繁体   English

windows程序中的WM_QUIT、WM_CLOSE、WM_DESTROY有什么区别?

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

我想知道 Windows 程序中的 WM_QUIT、WM_CLOSE 和 WM_DESTROY 消息之间有什么区别,本质上是:它们何时发送,除了程序定义的内容之外,它们是否有任何自动效果?

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. WM_CLOSE在窗口关闭时发送到窗口 - 单击其“X”按钮,或从窗口菜单中选择“关闭”,或在窗口具有焦点时按下Alt-F4 ,等等。如果你抓住了这个消息,这是您决定如何对待它 - 忽略它,或者真正关闭窗口。 By default, WM_CLOSE passed to DefWindowProc() causes the window to be destroyed.默认情况下, WM_CLOSE传递给DefWindowProc()会导致窗口被销毁。

WM_DESTROY is sent to the window when it starts to be destroyed. WM_DESTROY在窗口开始被销毁时被发送到窗口。 In this stage, in opposition to WM_CLOSE , you cannot stop the process, you can only make any necessary cleanup.在这个阶段,与WM_CLOSE相反,您不能停止该过程,您只能进行任何必要的清理。 When you catch WM_DESTROY , none of its child windows have been destroyed yet.当您捕获WM_DESTROY ,它的子窗口还没有被销毁。

WM_NCDESTROY is sent to the window when it is finishing being destroyed. WM_NCDESTROY在窗口完成销毁时发送到窗口。 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). WM_QUIT与任何窗口都不相关(从GetMessage()得到的hwnd为 NULL,并且没有调用任何窗口过程)。 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.GetMessage()读取WM_QUIT ,它返回 0 以表明这一点。 Take a look at a typical message loop snippet - the loop is continued while GetMessage() returns non-zero.看看一个典型的消息循环片段- 当GetMessage()返回非零值时,循环继续。

WM_QUIT can be sent by the PostQuitMessage() function. WM_QUIT可以由PostQuitMessage()函数发送。 This function is usually called when the main window receives WM_DESTROY (see a typical window procedure snippet ).该函数通常在主窗口接收到WM_DESTROY时调用(参见典型的窗口过程片段)。

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.首先, WM_CLOSEWM_DESTROY消息与特定窗口相关联,而WM_QUIT消息适用于整个应用程序(井线程)并且该消息永远不会通过窗口过程( WndProc例程)接收,而只能通过GetMessagePeekMessage职能。

In your WndProc routine the DefWindowProc function takes care of the default behavoir of these messages.WndProc例程中, DefWindowProc函数负责处理这些消息的默认行为。 The WM_CLOSE messages requests that the application should close and the default behavoir for this is to call the DestroyWindow function. WM_CLOSE消息请求关闭应用程序,默认行为是调用DestroyWindow函数。 Its when this DestroyWindow function is called that the WM_DESTROY message is sent.当这个DestroyWindow函数被调用时, WM_DESTROY消息被发送。 Notice that the WM_CLOSE is only a message requesting that you close (like WM_QUIT ) - you don't actually have to exit/quit.请注意, WM_CLOSE只是一条要求您关闭的消息(如WM_QUIT )-您实际上不必退出/退出。 But the WM_DESTROY message tells you that your window IS being closed and destroyed so you must cleanup any resources, handles etc.但是WM_DESTROY消息告诉你,你的窗口正在关闭和破坏,所以你必须清除任何资源,把手等。

Just so it doesn't get lost in the comments... don't forget about WM_CANCEL .只是为了不会在评论中迷失……不要忘记WM_CANCEL When you click the close (x) button on an MFC dialog, it will certainly send WM_CLOSE .当您单击 MFC 对话框上的关闭 (x) 按钮时,它肯定会发送WM_CLOSE The default OnClose() function will then call the default (base class) OnCancel() function.然后默认的OnClose()函数将调用默认的(基类) OnCancel()函数。

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.但是,如果您只是键入ESC键,这将导致对话框关闭,但是(据我所知)不会生成WM_CLOSE事件 - 它直接进入WM_CANCEL/OnCancel()机制。

I hereby invite the community to elaborate on this... or edit that elaboration into the accepted answer.我特此邀请社区对此进行详细说明……或将该详细说明编辑为已接受的答案。

At first let's discuss WM_QUIT - the difference from another messages that this is not associated with window.首先让我们讨论 WM_QUIT - 与其他消息的区别,这与窗口无关。 It is used by application.它由应用程序使用。 For example this can be handled by non-visible standalone OLE server (.exe, but not in-proc as .dll)例如,这可以由不可见的独立 OLE 服务器处理(.exe,但不能作为 .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_CLOSE - 根据 msdn:“应用程序可以在销毁窗口之前提示用户进行确认” - 它用作有关关闭意图的通知(您可以拒绝此意图)。

WM_DESTROY - is a fact that window is closing and all resources must(!) be deallocated. WM_DESTROY - 窗口正在关闭并且必须(!)释放所有资源的事实。

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.所以WM_CLOSE只是为了我们可以请求销毁窗口。 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.并且WM_DESTROY在默认情况下实际上并不发布退出消息,因为您可以有多个窗口。 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.如果需要,您可以让WM_CLOSE调用PostQuitMessage(exit)并在消息循环后销毁您的窗口。

If you wanted a custom close button in your game, it should do what WM_CLOSE does.如果你想在你的游戏中自定义关闭按钮,它应该做WM_CLOSE所做的。

Also there is the function CloseWindow(hwnd) , however it simply minimizes the window.还有函数CloseWindow(hwnd) ,但它只是最小化窗口。

Hope this helps anyone.希望这可以帮助任何人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM