深入分析Windows消息机制

2011-04-16 09:15王光辉
电脑与电信 2011年2期
关键词:句柄调用队列

王光辉

(成都理工大学信息科学与技术学院,四川成都610059)

1.引言

Windows操作系统是基于消息响应机制的被动式系统。Windows应用程序是消息驱动[1]程序,又称事件驱动程序。事件驱动意味着操作系统的每一部分之间以及操作系统与应用程序之间是通过“消息”进行通信联系的。由此可见,消息机制在Windows应用编程[2]的重要性。

2.消息

2.1 消息定义

消息是指Windows发出的一个通知[3],告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口大小、按下键盘上的一个键都会使Windows发送一个消息给应用程序。它可以由硬件、Windows、应用程序共同产生。消息通常分为以下四种:

(1)标准消息:除了WM_COMMAND,所有的以WM开头的消息都是标准消息。如窗口、鼠标移动、窗口大小改变等。程序启动或退出甚至每一段固定的时间都会产生标准Windows消息。

(2)命令消息:来自于菜单、加速键、工具栏按钮的消息,这类消息都以WM_COMMAND形式呈现。

(3)通知消息:由控件产生的消息。按键和鼠标的单击列表框都会产生这类消息[4],这类消息的目的是为了向父窗口(通常是对话框)通知事件的发生,它也是以WM_COMMAND形式呈现的。

(4)用户自定义的消息。

2.2 消息结构

在Windows程序中,消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其它信息,由MSG结构体表示。MSG结构体的定义如下:

在MSG结构中,消息是由一个消息名称(UINT)和两个参数(WPARAM,LPARAM)组成。当用户进行了输入或者窗口的状态发生改变时,系统都会发送消息到某一个窗口。例如,当菜单点中之后会有WM_COMMAND消息发送。其中,WPARAM的高字节(HIWORD(wParam))是命令的ID号,是菜单ID。同时,用户能定义自己的消息名称,也能利用自定义消息来发送通知和传送数据。

系统通过窗口句柄在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由指定窗口接收。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。句柄决定消息被发送到哪个窗口。

2.3 消息发送

在Windows中发送消息时,一般使用PostMessage()和SendMessage()函数[5],但是它们在发送方式上有些差别。二者最基本的区别在于SendMessage()通过调用窗口过程,把消息立即发往另一个窗口并且等到该消息被处理完后才返回。PostMessage()是把消息封装成一个MSG结构,投递到消息队列中,然后立即返回,无需等待。因此,PostMessage()是异步的,SendMessage()是同步的;PostMessage()只负责将消息放到消息队列中,不确定何时处理。SendMessage()要等到收到消息处理的返回码(DWord类型)后才继续;PostMessage()执行后马上返回,SendMessage()必须等到消息被处理后才会返回。

3.Windows消息机制

Windows消息机制是由消息队列、消息循环和窗口过程三个部分组成。

3.1 消息队列

Windows为所有消息维护着一个系统消息队列,而对于每一个应用程序,系统又将会创建一个对应的消息队列。Windows根据消息结构的内容将不同的消息发送给相应应用程序的消息队列。应用程序通过PeekMessage()或GetMessage()函数从Windows消息队列中获取消息,然后分派给某个窗口。Windows保存的消息队列是以线程(Thread)来分组的,即每个线程都有自己的消息队列。

3.2 消息循环

通过Windows消息循环机制[6],应用程序能从消息队列中检索消息,再把它分派给适当的窗口。然后继续从消息队列中检索下一条消息,再分派给适当的窗口,依次进行。函数的原型为:

消息循环以GetMessage()调用开始,它从消息队列中取出一个消息。当取出的消息为WM_QUIT(退出消息),消息循环和应用程序退出。TranslateMessage()函数将键盘按键的虚拟码转换为ASCII码,同时将WM_CHAR消息发送到消息队列中。DispatchMessage()函数将消息转发给Windows操作系统来调用相应的窗口过程函数处理。如果消息队列为空,应用程序就将控制权交还给Windows。如果有需要控制权的应用程序,Windows就将控制权转交给应用程序。这种控制权的交换使得Windows成为多任务的操作系统。

3.3 窗口过程

窗口过程是用来接收传递给窗口的消息,它的任务就是获取消息然后响应它。任何一个窗口类都有一个窗口过程。同一个类的窗口使用同样的窗口过程来响应消息。窗口过程是一个回调函数(Callback Function),它是由Windows操作系统负责调用的,而应用程序本身不能调用它。消息的处理是由窗口过程完成的,窗口过程处理了一个消息后,通常要返回一个值给Windows。系统发送消息给窗口过程,通常将消息数据作为参数传递给它。消息到来之后,窗口过程按照消息类型的排序进行处理,其中的参数则用来区分不同的消息。同时,窗口过程使用参数产生合适行为。下面是一个典型窗口过程的伪代码:

Windows的操作会产生大量的不同种类的消息,窗口过程函数不可能处理所有的消息,只处理需要的消息,其它的消息就交给系统处理。DefaultWndProc()就是系统提供的处理其它程序里没有捕获的消息。

3.4 Windows消息机制实现过程

Windows消息机制的具体实现过程,如图1所示:

图1 Windows消息机制

一个消息从产生到被一个窗口响应,主要有5个步骤:

(1)系统中发生了某个事件;

(2)Windows把这个事件翻译为消息,把它放到系统消息队列中,然后转发到相应线程消息队列里;

(3)应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中;

(4)应用程序把消息传递给系统,系统调用适当的窗口过程;

(5)窗口过程响应这个消息并进行处理。

在Windows消息机制中,步骤3和4构成了应用程序的消息循环。消息循环使应用程序能够响应外部的事件,所以,它是Windows应用程序的核心。消息循环的任务就是从消息队列中检索消息,然后把消息传递给适当的窗口。如果消息队列中没有消息,Windows就允许其它应用程序处理它们的消息。

4.结束语

消息机制是Windows应用程序工作的核心,利用各种开发工具在此平台上进行开发,不可避免地要与消息处理打交道。本文从消息的结构、发送、处理介绍了Windows消息机制。对于一个编写Windows程序的程序员来说,理解Windows消息机制的运行原理对于编写Windows应用程序是十分有益的。

[1]陈希胜.基于WINDOWS下的DMA编程[J].科技广场,2008,12:121.

[2]周金萍,徐丙立等.Windows系统编程[M].北京:人民邮电出版社,2002.7.

[3]王芳.Windows消息机制在VB编程中的应用[J].信息技术,2005(7):146.

[4]徐静蓉,赵雷,杨季文.消息分层处理机制在Windows应用程序开发中的应用[J].苏州大学学报(自然科学版),2006,22(1):61.

[5]张朝霞.MFC对消息的管理初探[J].内蒙古科技与经济,2004(23):55.

[6]李元臣.Windows的消息循环与Delphi中的消息机制[J].洛阳师范学院学报,2001(2):74.

猜你喜欢
句柄调用队列
队列里的小秘密
基于多队列切换的SDN拥塞控制*
核电项目物项调用管理的应用研究
在队列里
LabWindows/CVI下基于ActiveX技术的Excel调用
高校图书馆持久标识符应用研究
丰田加速驶入自动驾驶队列
编译程序语法分析句柄问题分析与探讨
基于系统调用的恶意软件检测技术研究
利用RFC技术实现SAP系统接口通信