Windows的消息处理机制

一、Windows的消息系统是由3个部分组成的:

1· 消息队列。Windows能够为所有的应用程序维护一个消息队列。应用程序必须从消息队列中获取消息,然后分派给某个窗口。

2· 消息循环。通过这个循环机制应用程序从消息队列中检索消息,再把它分派给适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适当的窗口,依次进行。

窗口过程。每个窗口都有一个窗口过程来接收传递给窗口的消息,它的任务就是获取消息然后响应它。窗口过程是一个回调函数;处理了一个消息后,它通常要返回一个值给Windows。

注意:回调函数是程序中的一种函数,它是由Windows或外部模块调用的。

二、Windows应用程序的消息处理机制(总结):

(1)操作系统收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。

(2)应用程序在消息循环中调用GetMessage函数从消息队列中取出一条一条的消息。取出消息后,应用程序可以对消息进行一些预处理,例如,放弃对某些消息的响应,或者调用TranslateMessage产生新的消息。

(3)应用程序调用DispatchMessage,将消息回传给操作系统。消息是由MSG结构体对象进行表示的,其中就包含了接收消息的窗口的句柄hwnd。因此,DispatchMessage函数总能进行正确的传递。

(4)系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理(即“系统给应用程序发送了消息”)。

以上就是Windows应用程序的消息处理过程。

三、细节

while(GetMessage (&msg, NULL, 0, 0))
{
    TranslateMessage (&msg);
    DispatchMessage (&msg);
}

消息队列中放置的消息是以MSG结构的形式存在,MSG包括:窗口句柄消息标识消息的两个参数(WPARAM和LPARAM)、消息发送(POST)的时间以及鼠标的位置。

msg变量是型态为MSG的结构,型态MSG在WINUSER.H中定义如下:

typedef struct tagMSG
{
    HWND hwnd ;    //记录窗口
    UINT message ;
    WPARAM wParam ;
    LPARAM lParam ;
    DWORD time ;   //消息时间
    POINT pt ;     //鼠标位置
}MSG, *PMSG ;

POINT数据型态也是一个结构,它在WINDEF.H中定义如下:

typedef struct tagPOINT
{
    LONG x ;
    LONG y ;
}POINT, * PPOINT;

TranslateMessage(&msg):将msg结构传给Windows,进行一些键盘转换。

DispatchMessage(&msg):又将msg结构回传给Windows。

然后,Windows将该消息发送给适当的窗口消息处理程序,让它进行处理。这也就是说,Windows将呼叫窗口消息处理程序。在HELLOWIN中,这个窗口消息处理程序就是WndProc函数。

处理完消息之后,WndProc传回到Windows。此时,Windows还停留在DispatchMessage呼叫中。在结束DispatchMessage呼叫的处理之后,Windows回到HELLOWIN程序中,并且接着从下一个GetMessage呼叫开始消息循环。

四、队列化消息与非队列化消息

消息能够被分为「队列化的」和「非队列化的」。

1. 队列化的消息是由Windows放入程序消息队列中的。在程序的消息循环中,重新传回并分配给窗口消息处理程序。

2. 非队列化的消息在Windows呼叫窗口时直接送给窗口消息处理程序。也就是说,队列化的消息被「发送」给消息队列,而非队列化的消息则「发送」给窗口消息处理程序。任何情况下,窗口消息处理程序都将获得窗口所有的消息--包括队列化的和非队列化的。窗口消息处理程序是窗口的「消息中心」。

1. 队列化消息基本上是使用者输入的结果,以击键(如WM_KEYDOWN和WM_KEYUP消息)、击键产生的字符(WM_CHAR)、鼠标移动(WM_MOUSEMOVE)和鼠标按钮(WM_LBUTTONDOWN)的形式给出。队列化消息还包含时钟消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUIT)

2. 非队列化消息则是其它消息。在许多情况下,非队列化消息来自呼叫特定的Windows函数。例如,当WinMain呼叫CreateWindow时,Windows将建立窗口并在处理中给窗口消息处理程序发送一个WM_CREATE消息。当WinMain呼叫ShowWindow时,Windows将给窗口消息处理程序发送WM_SIZE和WM_SHOWWINDOW消息。当WinMain呼叫UpdateWindow时,Windows将给窗口消息处理程序发送WM_PAINT消息。键盘或鼠标输入时发出的队列化消息信号,也能在非队列化消息中出现。例如,用键盘或鼠标选择了一个菜单项时,键盘或鼠标消息就是队列化的,而说明菜单项已选中的WM_COMMAND消息则可能就是非队列化的

五、

5.1 消息队列分类

    系统消息队列:由系统维护的消息队列(这个队列非常庞大),存放系统产生的所有消息,例如鼠标、键盘等
    程序消息队列:属于每一个应用程序(线程)的消息队列,由应用程序(线程)维护

5.2 消息和队列关系

    消息和消息队列的关系
        当鼠标、键盘产生消息时,会将消息放到系统消息队列。系统会根据存放的消息,找到对应程序的消息队列,将消息投递到程序的消息队列中。
    根据消息和消息队列之间使用关系,将消息分成两类
        队列消息:消息的发送和获取,都是通过消息队列完成;
        非队列消息:消息的发送和获取,是直接调用消息的窗口处理完成(就是消息不进队列直接调用消息处理函数对消息进行处理)
注意:

非队列消息:直接送给目的窗口的窗口过程;

队列消息由:DispatchMessage派发给目的窗口的窗口过程。

窗口过程被调用时接收四个参数:窗口句柄消息标识两个32位的消息参数。在窗口过程里,用switch/case分支处理语句来识别和处理消息。

参考:https://www.cnblogs.com/qinfengxiaoyue/archive/2013/02/12/2910614.html

你可能感兴趣的:(#,Windows消息机制,windows)