windows消息的循环机制

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

windows消息的循环机制
⾸先来了解⼏个基本概念:
消息:在了解什么是消息先来了解什么是事件。

事件可分为⼏种,由输⼊设备触发的,⽐如⿏标键盘等等。

由窗体控件触发的,⽐如button控件,file菜单等。

还有就是来⾃
Windows内部的事件。

这三种称为事件。

⽽消息,是由事件翻译⽽来的。

事件产⽣消息。

从数据结构⾓度来讲,消息是⼀种结构体。

结构如下:
typedef struct tagMSG
{
HWND hwnd; //窗⼝句柄。

UINT message;//消息类型。

WPARAM wParam;//32位附加信息。

LPARAM lParam;//32位附加信息。

DWORD time;//消息发送时间。

POINT pt;//消息发送时,⿏标所在位置。

}MSG;
消息队列:消息队列有两种,分为系统消息队列和应⽤程序消息队列。

产⽣的消息⾸先由Windows系统捕获,放在系统消息队列,再拷贝到对应的应⽤程序消息队列。

32/64位
系统为每⼀个应⽤程序维护⼀个消息队列。

消息循环:系统为每个应⽤程序维护⼀个消息循环,消息循环会不断检索⾃⾝的消息队列。

每有⼀个消息,就⽤GetMessage()取出消息。

while(GetMessage (&msg, NULL, 0, 0))//Windows消息循环。

{
TranslateMessage (&msg) ;//翻译消息,如按键消息,翻译为WM_CHAR
DispatchMessage (&msg) ;//分发消息到对应窗⼝
}
GetMessage具有阻塞机制。

当消息队列中没有消息时,程序⾮忙等,⽽是让权等待。

当收到WM_QUIT时,GetMessage返回false,循环停⽌,同时应⽤程序终⽌。

消息处理:DispatchMessage()把取出来的消息分配给相应的窗⼝或线程,由窗⼝过程处理函数DefWindowProc()处理。

==============================================================================================================================================================割割割割割
以上简要地介绍了消息队列,消息循环与消息处理的概念。

Windows的应⽤程序靠消息驱动来实现功能。

⽽消息驱动靠消息机制来处理。

消息机制就是由消息队列,消息循环,消息处理构成的。

那么,消息机制是如何运作的呢?
当⽤户运⾏⼀个应⽤程序,通过对⿏标的点击或键盘按键,产⽣⼀些特定事件。

由于Windows⼀直监控着I/O设备,该事件⾸先会被翻译成消息,由系统捕获,存放于系统消息队
列。

经分析,Windows知道该消息应由那个应⽤程序处理,则拷贝到相应的应⽤程序消息队列。

由于消息循环不断检索⾃⾝的消息队列,当发现应⽤程序消息队列⾥有消息,就
⽤GetMessage()取出消息,封装成Msg()结构。

如果该消息是由键盘按键产⽣的,⽤TranslateMessage()翻译为WM_CHAR消息,否则,⽤DisPatchMessage()将取出的消息分
发到相应的应⽤程序窗⼝,交由窗⼝处理程序处理。

Windows为每个窗体预留了过程窗⼝函数,该函数是⼀个回掉函数,由系统调⽤,应⽤程序不能调⽤。

程序员可以通过重载
该函数处理我们”感兴趣”的消息。

对于不感兴趣的消息,则由系统默认的窗⼝过程处理程序做出处理。

下⾯看这么⼀张图:
这张图很好地解释了消息机制的运⾏原理。

当运⾏程序->事件操作引发消息->消息先存在系统消息队列->再存⼊到应⽤程序消息队列->⽤消息循环提取消息->处理消息->再返回消息队列....
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
上⾯代码的执⾏过程为:
1. 消息循环调⽤GetMessage()从消息队列中查找消息进⾏处理,如果消息队列为空,程序将停⽌执⾏并等待(程序阻塞)。

2. 事件发⽣时导致⼀个消息加⼊到消息队列(例如系统注册了⼀个⿏标点击事件),GetMessage()将返回⼀个正值,这表明有消息需要被处理,并且消息已经填充到传⼊的MSG参数中;当传⼊WM_QUIT消息时返回0;
如果返回值为负表明发⽣了错误。

3. 取出消息(在Msg变量中)并将其传递给TranslateMessage()函数,这个函数做⼀些额外的处理:将虚拟键值信息转换为字符信息。

这⼀步实际上是可选的,但有些地⽅需要⽤到这⼀步。

4. 上⾯的步骤执⾏完后,将消息传递给DispatchMessage()函数。

DispatchMessage()函数将消息分发到消息的⽬标窗⼝,并且查找⽬标窗⼝过程函数,给窗⼝过程函数传递窗⼝句柄、消息、wParam、lParam等参数然
后调⽤该函数。

5. 在窗⼝过程函数中,检查消息和其他参数,你可以⽤它来实现你想要的操作。

如果不想处理某些特殊的消息,你应该总是调⽤DefWindowProc()函数,系统将按按默认的⽅式处理这些消息(通常认为是不做任何操
作)。

6. ⼀旦⼀个消息处理完成,窗⼝过程函数返回,DispatchMessage()函数返回,继续循环处理下⼀个消息。

相关文档
最新文档