Windows程序中的WM_QUIT,WM_CLOSE和WM_DESTROY有什么区别?


72

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


很好的任务
bvs

Answers:


92

他们是完全不同的。

WM_CLOSE当关闭窗口时将其发送到窗口-单击其“ X”按钮,或者从窗口菜单中选择“关闭”,或者Alt-F4在窗口具有焦点时按下窗口,等等。如果捕获此消息,则为您决定如何处理它-忽略它,或者真正关闭窗口。默认情况下,WM_CLOSE传递给DefWindowProc()导致窗口被销毁。

WM_DESTROY当它开始被销毁时被发送到窗口。在此阶段,与相对WM_CLOSE,您无法停止该过程,只能进行任何必要的清除。捕获时WM_DESTROY,它的所有子窗口都没有被破坏。

WM_NCDESTROY在完成销毁时将被发送到窗口。到此为止,它的所有子窗口都已被破坏。

WM_QUIT与任何窗口都不相关(“ hwndfrom”GetMessage()为NULL,并且不调用任何窗口过程)。此消息表明消息循环应停止并且应用程序应退出。当GetMessage()读取WM_QUIT,则返回0,这表示。看一看典型的消息循环代码片段-循环继续,而GetMessage()返回非零值。

WM_QUIT可以通过PostQuitMessage()功能发送。通常在接收主窗口时调用此函数WM_DESTROY(请参见典型的窗口过程片段)。


1
@ ad88非常适合添加用户注销/WM_ENDSESSION到达时发生的情况。这会自动触发WM_CLOSE / QUIT / DESTROY吗?
巴斯基(Basj)'17年

会话结束时,操作系统仅破坏了所有仍存在的剩余窗口,没有WM_CLOSE/WM_DESTROY消息发送给它们。他们有最后的机会通过清理进行清理WM_(QUERY)ENDSESSION。毕竟,所有赌注都没有了。请参阅当用户注销时Windows不会关闭窗口。那是您的电话
雷米·勒博

12

首先,WM_CLOSEWM_DESTROY消息与特定的窗口相关联,而WM_QUIT消息适用于整个应用程序(井线程),并且永远不会通过窗口过程(WndProc例程)接收消息,而只能通过GetMessagePeekMessage函数来接收。

在您的WndProc例程中,该DefWindowProc函数负责这些消息的默认行为。该WM_CLOSE消息请求,应用程序应该关闭,为此默认behavoir是调用DestroyWindow函数。当DestroyWindow调用此函数时,将发送WM_DESTROY消息。注意,WM_CLOSE只是一条消息,要求您关闭(如WM_QUIT)-实际上,您不必退出/退出。但是WM_DESTROY消息告诉你,你的窗口IS关闭和破坏,所以你必须清除任何资源,把手等。


2
不是整个应用程序,而是特定的消息循环。每个线程可能都有其自己的消息循环,因此一个应用程序可以具有多个消息循环。
0xC0000022L

6

只是为了确保它不会在评论中迷路...不要忘了WM_CANCEL。当您单击MFC对话框上的关闭(x)按钮时,它肯定会发送WM_CLOSE。然后,默认OnClose()函数将调用默认(基类)OnCancel()函数。

但是,如果仅键入ESC键,这将导致对话框关闭,但是(据我所知)却没有生成WM_CLOSE事件-它直接进入该WM_CANCEL/OnCancel()机制。

我在此邀请社区对此进行详细说明...或将该详细说明编辑为已接受的答案。


2

首先,让我们讨论WM_QUIT-与未与窗口关联的其他消息的区别。由应用程序使用。例如,这可以由不可见的独立OLE服务器(.exe,但不能作为.dll进行处理)处理。

WM_CLOSE-每个msdn:“应用程序可以在销毁窗口之前提示用户确认”-用作有关关闭意图的通知(您可以拒绝此意图)。

WM_DESTROY-是窗口正在关闭并且必须释放所有资源的事实。


@atzz是的,你是对的。一般而言,此消息通知事件循环完全停止处理,无论应用程序范围线程还是独立线程。
2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.