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进行两个数据库的数据 ...
随机推荐
- apple-touch-icon,shortcut icon和icon的区别
apple-touch-icon 可以了解到这是一个类似网站favicon的图标文件,用来在iphone和ipod上创建快捷键时使用. 这个文件应当是png格式,57x57像素大小,放在网站根目录之下 ...
- 18、GPS技术
GPS核心API Android SDK为GPS提供了很多API,其中LocationManager类是这些API的核心.LocationManager是一个系统服务类,与TelephonyManag ...
- 计算器显示e-005什么意思
计算器显示e-005什么意思 1e-005是科学表达式,即 =1e-5 =0.00001e+005就是乘以10的5次方 就是-1.4989*10^5 这是科学计数法(也叫指数计数法) 这是科学计数 ...
- android读取data下得数据
拥有Root权限的情况 adb shell su cd /data/data/com.package 然后就可以直接读取 没有Root的情况 adb shell run-as com.package ...
- forms
http://www.cnblogs.com/bomo/p/3309766.html http://www.cnblogs.com/leonwang/archive/2013/03/05/294457 ...
- kali系统安装图文教程
工具和原料 1.虚拟机:Oracle VM VirtualBox 下载地址:https://www.virtualbox.org/wiki/Downloads 根据你自己的计算机操作系统下载,其中如果 ...
- 使用sem_post信号量进行线程同步
写了一小段程序,测试一下线程同步的问题,如下: #include <stdio.h> #include <string.h> #include <semaphore.h& ...
- ACM 数论小结 2014-08-27 20:36 43人阅读 评论(0) 收藏
断断续续的学习数论已经有一段时间了,学得也很杂,现在进行一些简单的回顾和总结. 学过的东西不能忘啊... 1.本原勾股数: 概念:一个三元组(a,b,c),其中a,b,c没有公因数而且满足:a^2+b ...
- mysql编码详解
在开发程序的时候,我们使用mysql数据库开发的时候,有时会碰到自己明明输入的是中文,为什么数据库中存储的就是???? 1.在配置Connection URL时,加上?useUnicode=true& ...
- c语言中用宏定义一个常量,数字后面带个U, L, F的含义
转: c语言中数字后面带个U是什么意思?#define F_CPU 12000000U答:U表示该常数用无符号整型方式存储,相当于unsigned int;L表示该常数用长整型方式存储,相当于long ...