WM_QUIT,WM_CLOSE,WM_DESTROY 消息出现顺序及调用方式
http://bbs.ednchina.com/BLOG_ARTICLE_3005455.HTM
VC中WM_CLOSE、WM_DESTROY、WM_QUIT消息出现顺序及调用方式
wxleasyland@sina.com
2012.7
wxleasyland试验:
一、VC建的标准WIN32-HELLO WORLD程序中,
case WM_DESTROY:
// PostQuitMessage(0);将这行屏蔽
则点关闭,窗口关闭了,但是程序进程还在!要在任务管理器中中止。
二、VC建的标准WIN32-HELLO WORLD程序中,
1. 在WndProc()中加上
case WM_CLOSE:
WinExec("cmd /k echo WM_CLOSE: ",SW_SHOW);
break;
2. 按右上角的X、点图标\关闭、或者按ALT+F4,都只出现cmd窗,不会关闭程序。
因为原来是执行
default:
return DefWindowProc(hWnd, message, wParam, lParam);
即DefWindowProc来处理WM_CLOSE消息。现在被case WM_CLOSE:拦截了。
3. 点菜单里的FILE\EXIT,则就是执行case WM_COMMAND: 里的case IDM_EXIT: DestroyWindow(hWnd); 了。
不会执行
case WM_CLOSE:!!!
DestroyWindow(hWnd);
会销毁窗口,同时发送WM_DESTROY消息直接让WndProc()处理(不经过消息队列)。
三、VC建的标准WIN32-HELLO WORLD程序中,
1. 在WndProc()中加上
case WM_CLOSE:
WinExec("cmd /k echo WM_CLOSE: ",SW_SHOW);
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_DESTROY:
WinExec("cmd /k echo WM_DESTROY: ",SW_SHOW);
PostQuitMessage(0);
break;
2. 按右上角的X、点图标\关闭、或者按ALT+F4,会先出现WM_CLOSE,再出现WM_DESTROY。
3. 点菜单里的FILE\EXIT,则只出现WM_DESTROY。
四、VC建的标准WIN32-HELLO WORLD程序中,
如果用PostQuitMessage(0); 则不出现WM_CLOSE。
也不会出现WM_DESTROY!!!!!!! 窗口会关闭,程序退出。
这应该是正常的,WM_QUIT让GetMessage()为0,从而WinMain()退出,然后操作系统会自动去销毁窗口。
主程序已经没了,所以即使WM_DESTROY出现了也没用。
经试,在PostQuitMessage(0);后面的语句会继续执行到完。
PostQuitMessage只是产生一个WM_QUIT消息到消息队列中并马上返回。
所以标准WIN32程序是:
按右上角的X->出现 WM_CLOSE 销毁窗口->产生WM_DESTROY->运行PostQuitMessage->WinMain退出
菜单点EXIT->出现WM_COMMAND 运行 PostQuitMessage
五、在MFC对话框程序中,试验,是:
1. 先WM_CLOSE(这时窗口仍在显示)->再WM_DESTROY(窗口已经消失)->OnDestroy() 执行完后,程序完全退出
2. WM_CLOSE不一定会出现。WM_CLOSE 点右上角的X,点图标\关闭,或者按ALT+F4,会出现。 点OK按钮、或者Cancle按钮,或者用任务管理器强行中止,都不会出现。
3. WM_DESTROY 点右上角的X,点OK按钮、或者Cancle按钮,都会出现。而且晚于WM_CLOSE 出现。 用任务管理器强行中止,则不会出现。
4. 如果在程序中按一个按钮,里有PostQuitMessage(0); 则不出现WM_CLOSE,但会出现WM_DESTROY,窗口会关闭,程序退出。
经试,按钮函数里,在PostQuitMessage(0);后面的语句会继续执行到完。PostQuitMessage只是产生一个WM_QUIT消息到消息队列中并马上返回。
5. 如果在程序中按一个按钮,里有PostMessage(WM_DESTROY); 则不出现WM_CLOSE,但会出现WM_DESTROY。窗口不会关闭,还能正常用。
所以MFC对话框程序是:
按右上角的X->出现WM_CLOSE 销毁窗口->产生WM_DESTROY -> OnDestroy()执行完后程序退出
点确认或取消按钮 运行PostQuitMessage
==================================
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx
WM_CLOSE message
Sent as a signal that a window or an application should terminate.
A window receives this message through its WindowProc function.
窗口通过WindowProc函数来接收这个消息!
An application can prompt the user for confirmation, prior to destroying a window,
by processing the WM_CLOSE message and calling theDestroyWindow function only if the user confirms the choice.
程序中可以让用户确认是否真的要退出。
By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.
WM_DESTROY message
Sent when a window is being destroyed.
It is sent to the window procedure of the window being destroyed after the window is removed from the screen.
当窗口被从屏幕上删除掉之后,这个消息才被发送给窗口程序。
This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed.
During the processing of the message, it can be assumed that all child windows still exist.
在处理消息的过程中,所有子窗仍然存在。
A window receives this message through its WindowProc function.
窗口通过WindowProc函数来接收这个消息!
If the window being destroyed is part of the clipboard viewer chain (set by calling the SetClipboardViewer function),
the window must remove itself from the chain by processing the ChangeClipboardChain function
before returning from the WM_DESTROY message.
WM_NCDESTROY message
Notifies a window that its nonclient area is being destroyed.
The DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY message.
WM_NCDESTROY是在WM_DESTROY消息之后。
WM_DESTROY is used to free the allocated memory object associated with the window.
The WM_NCDESTROY message is sent after the child windows have been destroyed. I
n contrast, WM_DESTROY is sent before the child windows are destroyed.
A window receives this message through its WindowProc function.
窗口通过WindowProc函数来接收这个消息!
This message frees any memory internally allocated for the window.
WM_QUIT message
Indicates a request to terminate an application, and is generated when the application calls the PostQuitMessage function.
This message causes the GetMessage function to return zero.
The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure.
WM_QUIT消息与窗口没有关联,所以窗口处理程序收不到这个消息。
It is retrieved only by the GetMessage or PeekMessage functions.
Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.
PostQuitMessage function
Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.
The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately;
PostQuitMessage只是产生一个WM_QUIT消息到线程的消息队列中并马上返回。
the function simply indicates to the system that the thread is requesting to quit at some time in the future.
When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system.
The exit value returned to the system must be the wParam parameter of the WM_QUIT message.
DestroyWindow function
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, flushes the thread message queue, destroys timers, removes clipboard ownership,
and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows
when it destroys the parent or owner window.
The function first destroys child or owned windows, and then it destroys the parent or owner window.
会先销毁子窗,再销毁自身。
DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.
A thread cannot use DestroyWindow to destroy a window created by a different thread.
If the window being destroyed is a child window that does not have the WS_EX_NOPARENTNOTIFY style,
a WM_PARENTNOTIFY message is sent to the parent.
====================================
引用网络上的:
====================================
WM_QUIT,WM_CLOSE,WM_DESTROY
2010-05-27 10:35:20| 分类: 编程天地|字号 订阅
WM_DESTROY 是关闭程序
WM_CLOSE 是关闭窗口
WM_QUIT 是关闭消息环
WM_CLOSE和WM_DESTROY同属窗口消息,WM_QUIT则不在窗口消息之列。
三者先后执行顺序是WM_CLOSE、WM_DESTROY、WM_QUIT,
但需要注意的是MFC窗口默认取消按钮函数OnCancel()是不会触发WM_CLOSE消息,只触发WM_DESTROY。
WM_CLOSE:
在系统菜单里选择了“关闭”或者点击了窗口右上角的“X”按钮,你的窗口过程就会收到WM_CLOSE。
DefWindowProc对WM_CLOSE的处理是调用DestroyWindow。
当然,你可以不让DefWindowProc处理,而是自己处理,例如询问用户是否保存更改等。
如果用户选择“取消”,你忽略此消息,那么程序照常运行;如果用户确认要退出,你就调用DestroyWindow。
WM_DESTROY:
接下来,DestroyWindow完成窗口的清理工作,最后像窗口过程发送WM_DESTROY。
对于WM_DESTROY,DefWindowProc不会处理。
也就是说,你如果不处理这个消息,虽然你的窗口已经销毁,但进程并不会结束。
一般处理WM_DESTROY时都是释放资源(例如申请的内存等),然后调用PostQuitMessage。
WM_QUIT:
PostQuitMessage会发送WM_QUIT给消息队列。
注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,
从而结束消息循环,最后进程结束,程序退出。
假设使用者执行HELLOWIN,并且使用者最终单击了 Close按钮,或者假设用键盘或鼠标从系统菜单中选择了 Close,
DefWindowProc处理这一键盘或者鼠标输入,在检测到使用者选择了Close选项之后,它给窗口消息处理程序发送一条WM_SYSCOMMAND消息。
WndProc将这个消息传给DefWindowProc。
DefWindowProc给窗口消息处理程序发送一条WM_CLOSE消息来响应之。
WndProc再次将它传给DefWindowProc。
DestroyWindow呼叫DestroyWindow来响应这条WM_CLOSE消息。
DestroyWindow导致Windows给窗口消息处理程序发送一条WM_DESTROY消息。
WndProc再呼叫PostQuitMessage,将一条WM_QUIT消息放入消息队列中,以此来响应此消息。
这个消息导致WinMain中的消息循环终止,然后程序结束。
==========================================================================
WM_DESTROY, WM_CLOSE, WM_QUIT 区别 (2009-01-19 18:46:37)转载▼
标签: 预处理程序 close of message box it 分类: Win32API
开始我也很迷糊,后来看了相关的资料,现在明白了,我这里就转一些相关的文章吧.
WM_DESTROY, WM_CLOSE, WM_QUIT
WM_DESTROY 是关闭程序的
WM_CLOSE 是关闭窗口的
WM_QUIT 是关闭消息环的
以下是程序结束的过程:
1、使用者按[File/Close],系统发出WM_CLOSE消息
2、Frame把这条消息直接发给预处理程序
3、预处理程序发出WM_DESTROY消息
4、预处理程序收到WM_DESTROY后执行PostQuitMessage,发出WM_QUIT.
5、GetMessage收到这条消息后就推出消息循环,程序结束。
有三个消息看起来差不多,都是处理关闭的事情的。
它们是WM_DESTROY,WM_CLOSE,和WM_QUIT。
它们的确很相似,但你需要知道它们之间的不同!
一个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出。
你知道让用户作确认或有错误出现或有什么应该注意的事情发生的时候,往往弹出一个消息框。
插播:
消息框
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
* 当收到WM_CLOSE消息,你可以做两件事儿。
一件是你接受默认的处理返回一个值,你若这样做了,应用程序或窗口按照计划关闭;
再者,你返回0,应用程序或窗口将保持原样。以下是代码的基本部分:
if (msg == WM_CLOSE)
{
if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
return(0);
// otherwise, let the default handler take care of it
}
* WM_DESTROY消息有点儿不同。它是窗口正在关闭时发出的。
当得到WM_DESTROY消息的时候,窗口已经从视觉上被删除。
一个主窗口被关闭,并不意味着应用程序结束了,它将在没有窗口的条件下继续运行。
* 然而,当一个用户关闭了主窗口,也就意味着他要结束应用程序,
所以如果你希望应用程序结束,在收到WM_DESTROY消息的时候,你必须发出一个WM_QUIT消息。
WM_QUIT是应用程序结束发出的消息,一般可以看成进程被kill掉的情况.
=================================
参考网上的:
WM_DESTROY 是关闭程序的
WM_CLOSE 是关闭窗口的
WM_QUIT 是关闭消息环的
以下说明程序是如何退出的:
WM_QUIT,WM_CLOSE,WM_DESTROY 消息出现顺序及调用方式的更多相关文章
- WM_CLOSE WM_DESTROY WM_QUIT的区别
WM_CLOSE:关闭应用程序窗口 WM_DESTROY:关闭应用程序 WM_QUIT:关闭消息循环
- rocketmq总结(消息的顺序、重复、事务、消费模式)
rocketmq总结(消息的顺序.重复.事务.消费模式) 参考: http://www.cnblogs.com/wxd0108/p/6038543.html https://www.cnblogs.c ...
- 分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)
备注:1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现分布式系统可扩展 ...
- Pulsar の 保证消息的顺序性、幂等性和可靠性
原文链接:Pulsar の 保证消息的顺序性.幂等性和可靠性 一.背景 前面两篇文章,已经介绍了关于Pulsar消费者的详细使用和自研的Pulsar组件. 接下来,将简单分析如何保证消息的顺序性.幂等 ...
- 高可用保证消息绝对顺序消费的BROKER设计方案
转自: http://www.infoq.com/cn/articles/high-availability-broker-design?utm_source=tuicool&utm_medi ...
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”
在说到消息中间件的时候,我们通常都会谈到一个特性:消息的顺序消费问题.这个问题看起来很简单:Producer发送消息1, 2, 3... Consumer按1, 2, 3...顺序消费. 但实际情况却 ...
- 浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序
在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Li ...
- MQ如何解决消息的顺序性
一.消息的顺序性 1.延迟队列:设置一个全局变量index,根据实际情况一次按照index++的逻辑一次给消息队列设置延迟时间段,可以是0.5s,甚至1s; 弊端:如果A,B,C..消息队列消费时间不 ...
- 关于MQ的几件小事(五)如何保证消息按顺序执行
1.为什么要保证顺序 消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常.举例: 比如通过mysql binlog进行两个数据库的数据 ...
随机推荐
- 浅谈C#浅拷贝和深拷贝
近来爱上一本书<编写高质量代码,改善C#程序的157个建议>,我想很多人都想编写高质量的代码,因为我们不仅仅是码农,更是一名程序员. 从今天开始,我将每天和大家分享这本书中的内容,并加上自 ...
- linux 开机自动运行
1.开机启动时自动运行程序 Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置文件继续引导过程,启动其它进程.通常情况下,修改放置在 /etc/rc或 /et ...
- ylb:SQL 常用函数
ylbtech-SQL Server: SQL Server-SQL 常用函数 1,数学函数 2,日期和时间函数 3,字符串函数 4,转换函数 1,ylb:SQL 常用函数返回顶部 1,数学函数 2, ...
- 给编译好的DLL增加签名
两个步骤,记录如下,主要用在silverlight中引用的dll要签名时: "C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ildasm ...
- 【2013微软面试题】输出节点数为n的二叉树的所有形态
转自:http://blog.csdn.net/monsterxd/article/details/8449005 /* * 题意,求节点数为n的二叉树的所有形态,先要想个方式来唯一标示一棵二叉树 ...
- 《Linux命令行与shell脚本编程大全》 第一、二章 学习笔记
第一章:初识Linux shell Linux内核负责以下4个主要功能: 1.系统内存管理 2.软件程序管理 3.硬件设备管理 4.文件系统管理 1.系统内存管理 内核不仅管理服务器上的可用物理内存, ...
- fork()函数详解
linux中fork()函数详解(原创!!实例讲解) (转载) 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程 ...
- Redis批量导入数据
首先准备数据文件 格式为 SET Key0 Value0 SET Key1 Value1 ... SET KeyN ValueN 利用shell转换数据 #!/bin/bash while read ...
- Ubuntu上安装zsh
先安装zsh,同时移除之前可能的oh-my-zsh的安装 sudo apt-get install zsh if [ -d ~/.oh-my-zsh ]; then rm -r ~/.oh-my-zs ...
- Linux环境变量(小马哥推荐)
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. /etc/bashrc:为每一 ...