Windows的应用程序通常包含窗口(Window),它主要为用户提供一种可视化的交互方式(窗口是由线程(Thread)建立的).Windows 系统经过消息机制来让系统和用户进行交互,用户经过触发事件来触发消息,消息(Message)被发送,保存,处理,一个线程会维护本身的一套消息队列(Message Queue)[仅当线程有对应的建立窗口和处理窗口消息时候],在发生输入事件以后,Windows 系统将事件转换为一个消息并将消息放入程序的消息队列中.程序经过执行一块称之为「消息循环」的程序代码从消息队列中取出消息并调用窗体的回调函数处理消息,这样不只保持线程间的独占性.并且队列的以先进先出方式处理消息来实现异步通讯.windows
可是通常来讲不是全部的消息都是须要程序处理的.而是针对其中某些特定的消息进行处理.即程序只关心本身想关心的问题而不会多去处理其余没必要要的信息.可是系统并不会知道什么是程序所关心的消息,什么是程序不关心的消息,因此它会把全部的消息都发送给程序.那么程序便要从中塞选出本身想要处理的消息,而后把本身不想理会的消息过滤给系统,让系统去帮助处理这些不须要的消息(即系统提供的默认的窗口过程函数 DefWindowProc).那么通常程序的窗体过程具体流程以下:异步
上面能够看出窗体能够接收和处理消息的特性.然而控件其实也都是窗口.可是每一个控件却不必定都具备接收和处理消息的功能.由于在系统中只有具备句柄(一个系统自动维护的32位的数值,是做为系统对象的简单的惟一性的标识)的窗口才具备处理消息的特性.由于只有具备句柄的窗口才能独立存在做为一窗体存在.做为其余控件的容器.而没有句柄的控件,如Label,是不能独立存在的,只能做为窗口控件的子控件,它不能绘制自身,只能依靠父窗体将它绘制来.ide
消息由一个叫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 };spa
通常来讲消息可以被分为「队列化的」和「非队列化的」.操作系统
系统队列线程
当操做系统启动并初始化时,线程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个参数,分别是:指针
用户在操做程序时对电脑的操做这个事件将会被系统捕获到,而后把这个事件翻译成一个消息而且把消息投递到对应的消息队列中.而程序发现本身的消息队列中具备消息时它便会从本身的消息队列中取出消息并处理消息.直至消息队列为空为止.
Windows消息控制中心通常是三层结构,其顶端就是Windows内核.Windows内核维护着一个消息队列,第二级控制中心从这个消息队列中获取属于本身管辖的消息,后作出处理,有些消息直接处理掉,有些还要发送给下一级窗体(Window)或控件(Control).第二级控制中心通常是各Windows应用程序的Application对象.第三级控制中心就是Windows窗体对象,每个窗体都有一个默认的窗体过程,这个过程负责处理各类接收到的消息.
首先咱们要了解 windows 系统下程序是以消息为基础,事件驱动之.首先用户出发事件,而后系统把事件转换为对应的消息,而后把消息投递到消息队列中.应用程序经过消息循环得到消息,而后把消息转交个系统,有系统再把消息交给对应的窗口回调函数(系统经过以注册的窗口类结构中的一个指向回调函数指针的成员找到窗体的回调函数,而这个窗体结构体是在窗体建立过程当中设计窗体类时候经过定义一个 WNDCLASS 结构体设计窗体基本属性是定义的),经过窗口回调函数来处理消息,处理消息结束后,应用回调函数把权限在交还给系统而后,系统在执行权限交给应用程序.程序继续从消息队列中取出消息并按上述方法去处理消息之.流程以下: