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

面试题 相关文章推荐
Ibatis中如何提高SQL Map的性能
May 11 面试题
如何判断一段程序是由C 编译程序还是由C++编译程序编译的
Aug 04 面试题
数据库设计的包括哪两种,请分别进行说明
Jul 15 面试题
网络安全方面的面试题
Jan 07 面试题
用C#语言写出与SQLSERVER访问时的具体过程
Apr 16 面试题
what is the difference between ext2 and ext3
Nov 03 面试题
为什么要做架构设计
Jul 08 面试题
Ajax主要包含了哪些技术
Jun 12 面试题
用Python写一个for循环的例子
Jul 19 面试题
如何写一个自定义标签
Dec 28 面试题
请说出这段代码执行后a和b的值分别是多少
Mar 28 面试题
用JAVA实现一种排序,JAVA类实现序列化的方法(二种)
Apr 23 面试题
编写函数,将一个3*3矩阵转置
Oct 09 #面试题
用C或者C++语言实现SOCKET通信
Feb 24 #面试题
写出一个方法实现冒泡排序
Jul 08 #面试题
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
Apr 15 #面试题
写一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
Nov 18 #面试题
递归计算如下递归函数的值(斐波拉契)
Feb 04 #面试题
写出二分查找算法的两种实现
May 13 #面试题
You might like
php下正则来匹配dede模板标签的代码
2010/08/21 PHP
PHP学习之数组的定义和填充
2011/04/17 PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
2014/07/08 PHP
PHP获取中国时间(上海时区时间)及美国时间的方法
2017/02/23 PHP
PHP基于GD2函数库实现验证码功能示例
2019/01/27 PHP
PHP attributes()函数讲解
2019/02/03 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
2019/10/03 PHP
激活 ActiveX 控件
2006/10/09 Javascript
javascript中的location用法简单介绍
2007/03/07 Javascript
纯js实现背景图片切换效果代码
2010/11/14 Javascript
js 有框架页面跳转(target)三种情况下的应用
2013/04/09 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
多种方法实现JS动态添加事件
2013/11/01 Javascript
jQuery功能函数详解
2015/02/01 Javascript
JS实现超简单的仿QQ折叠菜单效果
2015/09/21 Javascript
AngularJs上传前预览图片的实例代码
2017/01/20 Javascript
详解JS: reduce方法实现 webpack多文件入口
2017/02/14 Javascript
浅谈js使用in和hasOwnProperty获取对象属性的区别
2017/04/27 Javascript
AngularJS日程表案例详解
2017/08/15 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
2018/09/20 Javascript
js中自定义react数据验证组件实例详解
2018/10/19 Javascript
jQuery实现文本显示一段时间后隐藏的方法分析
2019/06/20 jQuery
[59:08]Ti4 冒泡赛第二天 NEWBEE vs Titan 2
2014/07/15 DOTA
使用Python编写简单网络爬虫抓取视频下载资源
2014/11/04 Python
python 创建一个空dataframe 然后添加行数据的实例
2018/06/07 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
python小程序基于Jupyter实现天气查询的方法
2020/03/27 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
2020/08/07 Python
python脚本定时发送邮件
2020/12/22 Python
HTML5+CSS3 实现灵动的动画 TAB 切换效果(DEMO)
2017/09/15 HTML / CSS
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
2014党员四风对照检查材料思想汇报
2014/09/17 职场文书
交通事故死亡赔偿协议书
2014/12/03 职场文书
Spring中bean的生命周期之getSingleton方法
2021/06/30 Java/Android
SQL Server内存机制浅探
2022/04/06 SQL Server
SpringCloud Function SpEL注入漏洞分析及环境搭建
2022/04/08 Java/Android