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

面试题 相关文章推荐
天逸系统(武汉)有限公司Java笔试题
Dec 29 面试题
Oracle的内存结构(Memory structures)
Jun 10 面试题
如何在.net Winform里面显示PDF文档
Sep 11 面试题
.NET是怎么支持多种语言的
Feb 24 面试题
可以使用抽象函数重写基类中的虚函数吗
Jun 02 面试题
用C#语言写出在本地创建一个UDP接收端口的具体过程
Feb 22 面试题
广州某公司软件工程师面试题
Dec 22 面试题
分别介绍一下Session Bean和Entity Bean
Mar 13 面试题
排序都有哪几种方法?请列举。用JAVA实现一个快速排序
Feb 16 面试题
设置器与访问器的定义以及各自特点
Jan 08 面试题
介绍一下Java中标识符的命名规则
Feb 03 面试题
Delphi工程师笔试题
Sep 21 面试题
编写函数,将一个3*3矩阵转置
Oct 09 #面试题
用C或者C++语言实现SOCKET通信
Feb 24 #面试题
写出一个方法实现冒泡排序
Jul 08 #面试题
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
Apr 15 #面试题
写一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
Nov 18 #面试题
递归计算如下递归函数的值(斐波拉契)
Feb 04 #面试题
写出二分查找算法的两种实现
May 13 #面试题
You might like
php中的curl使用入门教程和常见用法实例
2014/04/10 PHP
学习php设计模式 php实现享元模式(flyweight)
2015/12/07 PHP
PHP使用自定义方法实现数组合并示例
2016/07/07 PHP
php获取目录下所有文件及目录(多种方法)(推荐)
2019/05/14 PHP
不能再简单的无闪刷新验证码原理很简单
2007/11/05 Javascript
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
2010/05/18 Javascript
jQuery 通过事件委派一次绑定多种事件,以减少事件冗余
2010/06/30 Javascript
js 实现css风格选择器(压缩后2KB)
2012/01/12 Javascript
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
2013/12/02 Javascript
JavaScript的removeChild()函数用法详解
2015/12/27 Javascript
基于jQuery实现数字滚动效果
2017/01/16 Javascript
JS+HTML+CSS实现轮播效果
2017/11/28 Javascript
如何开发出更好的JavaScript模块
2017/12/22 Javascript
vee-validate vue 2.0自定义表单验证的实例
2018/08/28 Javascript
原生js检测页面加载完毕的实例
2018/09/11 Javascript
js异步上传多张图片插件的使用方法
2018/10/22 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
JavaScript实现拖拽效果
2020/03/16 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
JavaScript逻辑运算符相关总结
2020/09/04 Javascript
Openlayers+EasyUI Tree动态实现图层控制
2020/09/28 Javascript
[03:58]兄弟们,回来开黑了!DOTA2昔日战友招募宣传视频
2016/07/17 DOTA
Python中的面向对象编程详解(下)
2015/04/13 Python
在Django的URLconf中使用多个视图前缀的方法
2015/07/18 Python
Phantomjs抓取渲染JS后的网页(Python代码)
2016/05/13 Python
Django Python 获取请求头信息Content-Range的方法
2019/08/06 Python
python3.8 微信发送服务器监控报警消息代码实现
2019/11/05 Python
关于Python turtle库使用时坐标的确定方法
2020/03/19 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
2020/06/24 Python
Lyle & Scott苏格兰金鹰官网:英国皇室御用品牌
2018/05/09 全球购物
英国最全面的橄榄球联盟门票网站:Live Rugby Tickets
2018/10/06 全球购物
日本最大美瞳直送网:Morecontact(中文)
2019/04/03 全球购物
欧克利英国官网:Oakley英国
2019/08/24 全球购物
烹饪自我鉴定
2014/03/01 职场文书
2014年创卫工作总结
2014/11/24 职场文书
个人工作失误的保证书怎么写?
2019/06/21 职场文书