所有Windows程序都是由消息驱动的,Windows有时也被称为“基于事件的、消息驱动的”操作系统。在Windows程序的执行过程中,只要用户进行了影响窗口的操作,都会触发相应的事件。操作系统每次检测到一个事件时,会给程序发一个消息,应用程序通过处理消息对用户的操作做出反应,这就是Windows程序的基本运行机理。
那么,GetMessage()与PeekMEssage()的区别是什么呢?
首先,我们看一下GetMessage()的简单用例:
while(GetMessage (&msg, NULL,0,0) )
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
消息循环从调用GetMessage()函数开始,该函数从消息队列中取出一个消息。上边的GetMessage()函数调用通过第一个参数为Windows系统传递一个MSG结构变量msg的地址。第二、三、四个参数设置为NULL或0,表示程序将接受它所创建的所有窗口的所有消息。
只要GetMessage()函数获取到非WM_QUIT消息,则执行while循环中的代码。
其中代码TranslateMessage(&msg);对键盘消息进行转换。
代码DispatchMessage(&msg);使windows系统将消息发送给适当的窗口过程,从而可以对消息进行处理。
下面,我们看一下另一种消息循环,PeekMessage(),代码示例如下:
MSG msg;
while(TRUE)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//进行其他处理
}
}
上面的消息循环和GetMessage的消息循环的主要区别是,GetMessage()函数不会讲控制返回给程序,直到它从程序的消息队列中获取消息,而PeekMessage()函数总是立刻返回,不管是否获取到消息。当消息队列中有消息时,PeekMessage()函数的返回值为TURE(非0),当队列中没有消息时返回FALSE(0)。
由于计算机的运行速度非常快,所以程序在运行过程中,经常会出现消息队列为空的情况,通过使用PeekMessage()函数可以充分利用这些时间进行其他处理。
如果有消息,PeekMessage()会立刻返回TRUE,按照通常的方式进行处理消息,如果消息队列中没有消息,PeekMessage()会立刻返回FLASE,在将控制返回给Windows系统之前,还可以进行其他的一些处理。
例如在游戏程序中,通常采用这种消息循环,当消息队列为空时,应用程序会不断地在窗口上绘制图像,使图像不断更新,从而得到连续的动画效果。