再上一篇:2.4 创建窗口
上一篇:2.5 显示窗口
主页
下一篇:2.7 窗口函数与消息处理
再下一篇:2.8 WM_PAINT消息
文章列表

2.6 消息循环

《Windows 下的 C/C++高级编程》讲述Windows环境下调用Win32 API函数程序设计

调用UpdateWindow之后,窗口就显示完毕。接下来程序必须准备读入用户通过鼠标或键盘输入的信息。我们知道,Windows是基于消息驱动机制的,Windows会为当前运行中的每一个Windows程序维护一个“消息队列”。在发生输入事件之后,Windows将事件转换为对应的“消息”,并将消息放入相应程序的消息队列中。

然后,程序从自己的消息队列中按一定的次序读取消息并发送给相应的窗口函数。代码:

while ( GetMessage( &msg, NULL, 0, 0 ) )

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

即用来实现“消息循环”。

首先,让我们来看一看其中涉及到的结构体。

这里的msg是一个MSG结构类型的变量。MSG结构在WINUSER.H中定义如下:

typedef struct tagMSG {

HWND hwnd;

UINT message;

WPARAM Param;

#第23页~ Windows下的C/C++高级编程

LPARAM lParam;

DWORD time;

POINT pt;

} MSG;

其中的POINT也是一个结构,用以表示屏幕上的一个点的坐标,其定义如下:

typedef struct tagPOINT {

LONG x;

LONG y;

} POINT;

消息结构(MSG)各个域的定义如下:

■ hwnd 接收消息的窗口的句柄。在 HelloWin 程序中只有一个窗口,其句柄由CreateWindow函数返回。

■ messag 消息标识符。这是一个索引数值(UINT:unsigned int),用以标识消息。每一个消息均有一个唯一对应的消息标识符。这些标识符在Windows头文件中定义,以WM_前缀开头。

■ wParam 一个32位的消息参数,其含义和数值根据消息的不同而不同。

■ lParam 一个32位的消息参数,其值与消息有关。

■ time 消息进入消息队列的时间。

■ pt 消息进入消息队列时鼠标的位置坐标。

消息循环从GetMessage调用开始,它从消息队列中取出一个消息,其定义如下:

BOOL GetMessage(

LPMSG lpMsg,

HWND hWnd,

UINT wMsgFilterMin,

UINT wMsgFilterMax

);

其中,参数lpMsg是一个指向MSG结构的指针。

hWnd参数是一个窗口句柄,用以指定接收属于哪一个窗口的消息。如果设置为NULL,则表示程序接收它自己创建的所有窗口的消息。

wMsgFilterMin 和 wMsgFilterMax 参数分别是将提取的消息的最小和最大索引值。GetMessage只提取消息队列中索引值在wMsgFilterMin和wMsgFilterMax之间的消息,其余的消息一概忽略。如果wMsgFilterMin和wMsgFilterMax均被置为0,则GetMessag将提取消息队列中的所有消息。

这里的函数调用:

GetMessage( &msg, NULL, 0, 0 );

表示程序将接收它自己所创建的所有窗口的所有消息。

Windows用从消息队列中提取的下一个消息来填充消息结构的各个域。

只要从消息队列中取出的消息的 message 域不为“WM_QUIT”(其值为 0x0012),GetMessage就返回一个非0值,否则GetMessage就返回一个0值。

语句

#第24页~

第2章 窗口和消息

TransateMessage( &msg );

用于将msg结构传给Windows以进行一些键盘转换,相关内容将在后面详细介绍。

语句

DispatchMessage( &msg );

再一次将msg结构传给Windows。然后由Windows将该消息发送给适当的窗口函数,让后者对消息进行相应的处理。也就是说,是 Windows调用窗口函数,而不是由程序员调用。在HelloWin中,这个窗口函数就是WndProc。在结束DispatchMessage调用的处理之后,流程又由Windows回到HelloWin,并且接着从下一个GetMessage调用开始继续消息循环。