解释一下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...

面试题 相关文章推荐
Yahoo-PHP面试题1
Jul 20 面试题
某IT外企面试题-二分法求方程!看看大家的C++功底
Jul 04 面试题
将一个文本文件的内容按倒序打印出来
Jan 05 面试题
Android笔试题总结
Nov 29 面试题
SQL SERVER面试资料
Mar 30 面试题
什么是事务?为什么需要事务?
Jan 09 面试题
delegate与普通函数的区别
Jan 22 面试题
亿阳信通股份有限公司C#笔试题
Dec 06 面试题
linux面试题参考答案(10)
Nov 04 面试题
设计模式的基本要素是什么
Apr 21 面试题
Java如何获得ResultSet的总行数
Sep 03 面试题
Unix/Linux开发面试题
Aug 16 面试题
编写函数,将一个3*3矩阵转置
Oct 09 #面试题
用C或者C++语言实现SOCKET通信
Feb 24 #面试题
写出一个方法实现冒泡排序
Jul 08 #面试题
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
Apr 15 #面试题
写一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
Nov 18 #面试题
递归计算如下递归函数的值(斐波拉契)
Feb 04 #面试题
写出二分查找算法的两种实现
May 13 #面试题
You might like
第八节 访问方式 [8]
2006/10/09 PHP
基于mysql的论坛(2)
2006/10/09 PHP
在IIS7.0下面配置PHP 5.3.2运行环境的方法
2010/04/13 PHP
php中全局变量global的使用演示代码
2011/05/18 PHP
PHP单例模式定义与使用实例详解
2017/02/06 PHP
理清PHP在Linxu下执行时的文件权限方法
2017/06/07 PHP
详解PHP多个进程配合redis的有序集合实现大文件去重
2019/03/06 PHP
HR vs CL BO3 第二场 2.13
2021/03/10 DOTA
常用一些Javascript判断函数
2012/08/14 Javascript
JQuery实现表格中相同单元格合并示例代码
2013/06/26 Javascript
jQuery下拉框的简单应用
2016/06/24 Javascript
Javascript中内建函数reduce的应用详解
2016/10/20 Javascript
Javascript自定义事件详解
2017/01/13 Javascript
H5手机端多文件上传预览插件
2017/04/21 Javascript
Angular通过angular-cli来搭建web前端项目的方法
2017/07/27 Javascript
vue基础之事件简写、事件对象、冒泡、默认行为、键盘事件实例分析
2019/03/11 Javascript
简单了解TypeScript中如何继承 Error 类
2019/06/21 Javascript
微信小程序之下拉列表实现方法解析(附完整源码)
2019/08/23 Javascript
JS函数参数的传递与同名参数实例分析
2020/03/16 Javascript
Jquery 获取相同NAME 或者id删除行操作
2020/08/24 jQuery
[03:10]超级美酒第四天 fy拉比克秀 大合集
2018/06/05 DOTA
python生成IP段的方法
2015/07/07 Python
python OpenCV学习笔记之绘制直方图的方法
2018/02/08 Python
对python以16进制打印字节数组的方法详解
2019/01/24 Python
Python3.6实现根据电影名称(支持电视剧名称),获取下载链接的方法
2019/08/26 Python
Pygame框架实现飞机大战
2020/08/07 Python
基于tensorflow __init__、build 和call的使用小结
2021/02/26 Python
利用CSS3的border-radius绘制太极及爱心图案示例
2016/05/17 HTML / CSS
意大利在线购买隐形眼镜网站:VisionDirect.it
2019/03/18 全球购物
雷曼兄弟的五金店:Lehman’s Hardware Store
2019/04/10 全球购物
英国最好的温室之家:Greenhouses Direct
2019/07/13 全球购物
中学生学习生活的自我评价
2013/10/26 职场文书
银行求职信范文
2019/05/13 职场文书
python析构函数用法及注意事项
2021/06/22 Python
vue实现在data里引入相对路径
2022/06/05 Vue.js
分享几个实用的CSS代码块
2022/06/10 HTML / CSS