Windows 应用程序交互过程
应用程序
Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视化的交互方式(窗口是由线程(Thread)创建的).Windows 系统通过消息机制来让系统和用户进行交互,用户通过触发事件来触发消息,消息(Message)被发送,保存,处理,一个线程会维护自己的一套消息队列(Message
Queue)[仅当线程有对应的创建窗口和处理窗口消息时候],在发生输入事件之后,Windows 系统将事件转换为一个消息并将消息放入程序的消息队列中.程序通过执行一块称之为「消息循环」的程序代码从消息队列中取出消息并调用窗体的回调函数处理消息,这样不仅保持线程间的独占性.而且队列的以先进先出方式处理消息来实现异步通信.
但是一般来说不是所有的消息都是需要程序处理的.而是针对其中某些特定的消息进行处理.即程序只关心自己想关心的问题而不会多去处理其他不必要的信息.但是系统并不会知道什么是程序所关心的消息,什么是程序不关心的消息,所以它会把所有的消息都发送给程序.那么程序便要从中塞选出自己想要处理的消息,然后把自己不想理会的消息过滤给系统,让系统去帮助处理这些不需要的消息(即系统提供的默认的窗口过程函数 DefWindowProc).那么一般程序的窗体过程具体流程如下:
上面可以看出窗体可以接收和处理消息的特性.然而控件其实也都是窗口.但是每个控件却不一定都具有接收和处理消息的功能.因为在系统中只有具有句柄(一个系统自动维护的32位的数值,是作为系统对象的简单的唯一性的标识)的窗口才具有处理消息的特性.因为只有具有句柄的窗口才能独立存在作为一窗体存在.作为其他控件的容器.而没有句柄的控件,如Label,是不能独立存在的,只能作为窗口控件的子控件,它不能绘制自身,只能依靠父窗体将它绘制来.
消息
消息载体
消息由一个叫MSG的结构体定义,包括窗口句柄(HWND),消息ID(UINT),参数(WPARAM, LPARAM)等等:
1 struct MSG
2 {
3 HWND hwnd;
4 UINT message;
5 WPARAM wParam;
6 LPARAM lParam;
7 DWORD time;
8 POINT pt;
9 };消息的简单分类
一般来说消息能够被分为「队列化的」和「非队列化的」.
- 队列化的消息是由Windows放入程序消息队列中的.在程序的消息循环中,重新传回并分配给窗口消息处理程序.即把消息发送给程序的消息队列中,等带消息处理函数取出并处理消息.队列化消息基本上是使用者输入的结果,以击键(如WM_KEYDOWN和WM_KEYUP消息)、击键产生的字符(WM_CHAR)、鼠标移动(WM_MOUSEMOVE)和鼠标按钮(WM_LBUTTONDOWN)的形式给出.队列化消息还包含时钟消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUIT).
- 非队列化的消息在Windows呼叫窗口时直接送给窗口消息处理程序.直接进行消息处理.非队列化消息则是其它消息.在许多情况下,非队列化消息来自呼叫特定的Windows函数.例如,当WinMain呼叫CreateWindow时,Windows将建立窗口并在处理中给窗口消息处理程序发送一个WM_CREATE消息.当WinMain呼叫ShowWindow时,Windows将给窗口消息处理程序发送WM_SIZE和WM_SHOWWINDOW消息.当WinMain呼叫UpdateWindow时,Windows将给窗口消息处理程序发送WM_PAINT消息.
- 注意: 键盘或鼠标输入时发出的队列化消息信号,也能在非队列化消息中出现.例如,用键盘或鼠标选择了一个菜单项时,键盘或鼠标消息就是队列化的,而说明菜单项已选中的WM_COMMAND消息则可能就是非队列化的.
- 任何情况下,窗口消息处理程序都将获得窗口所有的消息--包括队列化的和非队列化的
消息队列
- 系统队列
当操作系统启动并初始化时,线程Raw Input Thread(RIT)就会启动,并创系统硬件输入队列(System Hardware Input Queue)(SHIQ). 对于外部的硬件事件(鼠标或者键盘),硬件驱动会将事件转换成消息,并存放到SHIQ中,而RIT线程就专门负责处理SHIQ中的消息,把消息分发到对应线程的消息队列里面. - 线程队列
而对于线程来说,每个线程可以拥有自己的消息队列,它和线程一一对应.在线程刚创建时,消息队列并不会被创建,而是当GDI的函数调用发生时,Windows系统才认为有必要为线程创建消息队列.系统会为其维护一个THREADINFO结构.
消息队列包含在一个叫THREADINFO的结构中,有四个队列:- Sent Message Queue 发送消息队列 [该队列保存其他程序通过SendMessage给该线程发送的消息]
- Posted Message Queue 登记消息队列 [该队列保存其他队列通过PostMessage给该线程发送的消息]
- Visualized Input Queue 输入消息队列 [保存系统队列分发过来的消息,比如鼠标或者键盘的消息]
- Reply Message Queue 响应消息队列 [保存向窗体发送消息后的结果,比如sendMessage操作结束后,接收消息方会发送一个Reply消息给发送方的Reply队列中,以唤醒发送队列]
THREADINFO结构体定义如下图所示:
- 系统队列
消息管理机制
消息源
消息可以由Windows系统发送,也可以由应用程序本身;可以向线程内发送,也可以跨线程.主要是看发送函数的调用者.
附加参数:
系统向窗口发送的消息通常包含3个参数,分别是:
- 窗口句柄(a window handle):窗口句柄用来标识消息将要发送到的窗口对象,系统使用窗口句柄来确定哪一个窗口句柄应该接收该消息.
- 消息标识符(a message identifier):消息标识符是用来区分不同消息的命名常量,当窗口过程接收到一个消息时,它使用消息标识符来确定如何处理该消息.例如,消息标识符WM_PAINT告诉窗口过程“窗口的客户区已经发生变化,窗口必须进行重新绘制”.
- 消息参数(message parameters):消息参数用来表述窗口过程处理消息时所使用的数据或数据的位置,通常用一对参数表示(即2个长整型的参数:WPARAM, LPARAM).消息参数的意义和取值取决于消息.当不需要使用消息参数时,通常将其设置为NULL.窗口过程必须通过检查消息标识符来确定如何对消息参数进行解释.
传递过程:
用户在操作程序时对电脑的操作这个事件将会被系统捕获到,然后把这个事件翻译成一个消息并且把消息投递到对应的消息队列中.而程序发现自己的消息队列中具有消息时它便会从自己的消息队列中取出消息并处理消息.直至消息队列为空为止.
三级结构
Windows消息控制中心一般是三层结构,其顶端就是Windows内核.Windows内核维护着一个消息队列,第二级控制中心从这个消息队列中获取属于自己管辖的消息,后做出处理,有些消息直接处理掉,有些还要发送给下一级窗体(Window)或控件(Control).第二级控制中心一般是各Windows应用程序的Application对象.第三级控制中心就是Windows窗体对象,每一个窗体都有一个默认的窗体过程,这个过程负责处理各种接收到的消息.
总结
首先我们要了解 windows 系统下程序是以消息为基础,事件驱动之.首先用户出发事件,然后系统把事件转换为对应的消息,然后把消息投递到消息队列中.应用程序通过消息循环获得消息,然后把消息转交个系统,有系统再把消息交给对应的窗口回调函数(系统通过以注册的窗口类结构中的一个指向回调函数指针的成员找到窗体的回调函数,而这个窗体结构体是在窗体创建过程中设计窗体类时候通过定义一个 WNDCLASS 结构体设计窗体基本属性是定义的),通过窗口回调函数来处理消息,处理消息结束后,应用回调函数把权限在交还给系统然后,系统在执行权限交给应用程序.程序继续从消息队列中取出消息并按上述方法去处理消息之.流程如下:
转自:http://www.cnblogs.com/kzang/archive/2012/09/30/2709303.html
Windows 应用程序交互过程的更多相关文章
- JavaScript与C# Windows应用程序交互方法
一.建立网页 <html> <head> <meta http-equiv="Content-Language" content=&quo ...
- C# windows程序应用与JavaScript 程序交互实现例子
C# windows程序应用与JavaScript 程序交互实现例子 最近项目中又遇到WinForm窗体内嵌入浏览器(webBrowser)的情况,而且涉及到C#与JavaScript的相互交互问题, ...
- Windows程序执行过程
Windows应用程序: WinMain函数(入口函数): 1. 设计窗体类,注冊窗体类.WNDCLASS 2. 创建窗体,显示及更新窗体. 3. 消息循环. 窗体过程函数(回调函数):WindowP ...
- 【系统篇】从int 3探索Windows应用程序调试原理
探索调试器下断点的原理 在Windows上做开发的程序猿们都知道,x86架构处理器有一条特殊的指令——int 3,也就是机器码0xCC,用于调试所用,当程序执行到int 3的时候会中断到调试器,如果程 ...
- 升级Windows 10 正式版过程记录与经验
升级Windows 10 正式版过程记录与经验 [多图预警]共50张,约4.6MB 系统概要: 预装Windows 8.1中文版 64位 C盘Users 文件夹已经挪动到D盘,并在原处建立了符号链接. ...
- 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...
- DirectShow程序运行过程简析
这段时间一直在学习陆其明老师的<DirectShow开发指南>一书,书中对DirectShow的很多细节讲解清晰,但是却容易让人缺少对全局的把握.在学习过程中,整理了关于DirectSho ...
- windows进程/线程创建过程 --- windows操作系统学习
有了之前的对进程和线程对象的学习的铺垫后,我们现在可以开始学习windows下的进程创建过程了,我将尝试着从源代码的层次来分析在windows下创建一个进程都要涉及到哪些步骤,都要涉及到哪些数据结构. ...
- ASP.NET运行机制原理 ---浏览器与IIS的交互过程 自己学习 网上查了下别人写的总结的很好 就转过来了 和自己写的还好里嘻嘻
一.浏览器和服务器的交互原理 (一).浏览器和服务器交互的简单描述: 1.通俗描述:我们平时通过浏览器来访问网站,其实就相当于你通过浏览器去访问一台电脑上访问文件一样,只不过浏览器的访问请求是由被访问 ...
随机推荐
- ASIHTTPRequest缓存策略download cache
本文为大家介绍了iOS开发ASIHTTPRequest使用download cache的内容,其中包括cache策略,存储策略,其他cache相关的特性,编写自己的cache等等内容. 从1.8版本开 ...
- Python判断变量的数据类型的两种方法
https://www.cnblogs.com/jessicaxu/p/7727264.html
- [NLP] TextCNN模型原理和实现
1. 模型原理 1.1 论文 Yoon Kim在论文(2014 EMNLP) Convolutional Neural Networks for Sentence Classification提出Te ...
- Vue.js使用v-show和v-if的注意事项
这篇文章一开始先对Vue.js中v-show和v-if两者的区别进行了简单的介绍,而后通过图文详细给大家介绍了Vue.js使用v-show和v-if注意的事项,有需要的朋友们可以参考借鉴,下面来一起看 ...
- Windows Phone 8, 添加Map控件
摘要: 1. 添加Map控件到程序. 2. 在Map控件中显示您当前的位置. 内容: 首先在WMAppManifest.xml中的Capabilities选项卡中勾选如下两项:ID_CAP_MAP, ...
- SPSS教程学习笔记1:K个独立样本秩和检验及多重比较 (转载) (非参数假设检验)
本文地址:http://www.datasoldier.net/archives/173版权声明:本文为原创文章,版权归 数据小兵 所有,欢迎分享本文,转载请保留出处! 方差分析经常会出现不满 ...
- ubuntu16.04-caffe安装过程详解-草稿
前言 目前主要模块都是基于深度学习展开的,虽然知道一些深度学习的基础知识,只是皮毛,还没有使用深度学习框架练手甚至深入,故开始着手深度学习的实操和深入学习. 操作步骤 参考 1.Ubuntu16.04 ...
- CodeForces - 547D: Mike and Fish (转化为欧拉回路)(优化dfs稠密图)(定向问题)
As everyone knows, bears love fish. But Mike is a strange bear; He hates fish! The even more strange ...
- Flask第31课——include标签
我们在上一节代码基础上增加一些代码,样式: 文件名index.html,代码: {% from 'macros/forms.html' import input %} <!DOCTYPE htm ...
- Javascript 在严格模式下禁止指向 this
如下代码, f() 输出的是 false,而 f2() 输出的是 true. 这是因为 f2 在严格模式下禁止 this 指向全局,所以 this 是 undefined, !this 当然是 tru ...