解释一下Windows的消息机制


Posted in 面试题 onJanuary 30, 2014
Windows是一个消息(Message)驱动系统。Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理来完成。
Windows系统中有两种消息队列:系统消息队列和应用程序消息队列。计算机的所有输入设备由Windows监控。当一个事件发生时,Windows先将输入的消息放入系统消息队列中,再将消息拷贝到相应的应用程序消息队列中。应用程序的消息处理程序将反复检测消息队列,并把检测到的每个消息发送到相应的窗口函数中。这便是一个事件从发生至到达窗口函数必须经历的过程。
必须注意的是,消息并非是抢占性的,无论事件的缓急,总是按照到达的先后派对,依次处理(一些系统消息除外),这样可能使一些实时外部事件得不到及时处理。

Windows中的消息是放在对应的进程的消息队列里的。可以通过GetMessage取得,并且对于一般的消息,此函数返回非零值,但是对于WM_QUIT消息,返回零。可以通过这个特征,结束程序。当取得消息之后,应该先转换消息,再分发消息。所谓转换,就是把键盘码的转换,所谓分发,就是把消息分发给对应的窗口,由对应的窗口处理消息,这样对应窗体的消息处理函数就会被调用。两个函数可以实现这两个功能:TranslateMessage和DispatchMessage。
另外,需要注意,当我们点击窗口的关闭按钮关闭窗口时,程序并没有自动退出,而是向程序发送了一个WM_DESTROY消息(其实过程是这样的,首先向程序发送WM_CLOSE消息,默认的处理程序是调用DestroyWindow销毁窗体,从而引发WM_DESTROY消息),此时在窗体中我们要响应这个消息,如果需要退出程序,那么就要向程序发送WM_QUIT消息(通过PostQuitMessage实现)。一个窗体如果想要调用自己的消息处理函数,可以使用SendMessage向自己发消息。
如上所述,大部分(注意是大部分)的消息是这样传递的:首先放到进程的消息队列中,之后由GetMessage取出,转换后,分发给对应的窗口。这种消息成为存储式消息。存储式消息基本上是使用者输入的结果,以击键(如WM_KEYDOWN和WM_KEYUP讯息)、击键产生的字符(WM_CHAR)、鼠标移动(WM_MOUSEMOVE)和鼠标按钮(WM_LBUTTONDOWN)的形式给出。存储式消息还包含时钟消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUIT)。但是也有的消息是直接发送给窗口的,它们被称为非存储式消息。例如,当WinMain调用CreateWindow时,Windows将建立窗口并在处理中给窗口消息处理函数发送一个WM_CREATE消息。当WinMain调用ShowWindow时,Windows将给窗口消息处理函数发送WM_SIZE和WM_SHOWWINDOW消息。当WinMain调用UpdateWindow时,Windows将给窗口消息处理函数发送WM_PAINT消息。

Tags in this post...

面试题 相关文章推荐
PHP面试题及答案一
Jun 18 面试题
Java TransactionAPI (JTA) 主要包含几部分
Dec 07 面试题
纬创Java面试题笔试题
Oct 02 面试题
某公司Java工程师面试题笔试题
Mar 27 面试题
亿阳信通股份有限公司笔试题(C#)
Mar 04 面试题
关于递归的一道.NET面试题
May 12 面试题
金士达面试非笔试
Mar 14 面试题
What's the difference between an interface and abstract class? (接口与抽象类有什么区别)
Oct 29 面试题
Shell如何接收变量输入
Aug 06 面试题
一套比较完整的软件测试人员面试题
May 13 面试题
How to spawning asynchronous work in J2EE
Aug 29 面试题
介绍下java.util.Arrays类
Oct 16 面试题
编写函数,将一个3*3矩阵转置
Oct 09 #面试题
用C或者C++语言实现SOCKET通信
Feb 24 #面试题
写出一个方法实现冒泡排序
Jul 08 #面试题
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
Apr 15 #面试题
写一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
Nov 18 #面试题
递归计算如下递归函数的值(斐波拉契)
Feb 04 #面试题
写出二分查找算法的两种实现
May 13 #面试题
You might like
VFP与其他应用程序的集成
2006/10/09 PHP
在PHP里得到前天和昨天的日期的代码
2007/08/16 PHP
PHP数组操作――获取数组最后一个值的方法
2015/04/14 PHP
最新制作ThinkPHP3.2.3完全开发手册
2015/11/23 PHP
Thinkphp实现自动验证和自动完成
2015/12/19 PHP
yii2 在控制器中验证请求参数的使用方法
2019/06/19 PHP
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
浅谈javascript的数据类型检测
2010/07/10 Javascript
jquery ajax同步异步的执行最终解决方案
2013/04/26 Javascript
利用Keydown事件阻止用户输入实现代码
2014/03/11 Javascript
三种AngularJS中获取数据源的方式
2016/02/02 Javascript
jquery操作select元素和option的实例代码
2016/02/03 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
js实现千分符和保留几位小数的简单实例
2016/08/01 Javascript
vue2.0实现前端星星评分功能组件实例代码
2018/02/12 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
vue2.0+koa2+mongodb实现注册登录
2018/04/10 Javascript
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)
2019/12/04 Javascript
Vue组件模板及组件互相引用代码实例
2020/03/11 Javascript
一个简单的python程序实例(通讯录)
2013/11/29 Python
python中使用urllib2伪造HTTP报头的2个方法
2014/07/07 Python
python自动化测试之setUp与tearDown实例
2014/09/28 Python
django中的图片验证码功能
2019/09/18 Python
python如何快速生成时间戳
2020/07/21 Python
jupyter 添加不同内核的操作
2021/02/06 Python
美赞臣新加坡官方旗舰店:Enfagrow新加坡
2019/05/15 全球购物
YBF Beauty官网:美丽挚友,美国知名彩妆品牌
2020/11/22 全球购物
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
为什么在使用动态 SQL 语句时必须为低层数据库对象授予权限
2012/12/13 面试题
教师个人自我鉴定
2014/02/08 职场文书
事业单位绩效考核实施方案
2014/03/27 职场文书
纪念九一八事变演讲稿:忘记意味着背叛
2014/09/14 职场文书
小学生纪律委员竞选稿
2015/11/19 职场文书
煤矿安全生产管理协议书
2016/03/22 职场文书
Nginx 502 Bad Gateway错误原因及解决方案
2021/03/31 Servers
pytorch中的model=model.to(device)使用说明
2021/05/24 Python