Windows编程:PeekMessage函数

在工作中经常会有这样的需求,即要求程序在空新诗的时候执行某种额外的操作.实际上,Windows中有很多「闲置时间」,在这个时间内,所有消息队列为空,Windows只停在一个小循环中等待键盘或者鼠标输入。我们能否在闲置时间内获得控制,绘制矩形,并且只在有消息加入程序的消息队列之后才释放控制呢?这就是PeekMessage函数的目的之一。下面是PeekMessage呼叫的一个例子:

PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) ;

       

前面的四个参数(一个指向MSG结构的指针、一个窗口句柄、两个值指示消息范围)与GetMessage的参数相同。将第二、三、四个参数设定为NULL0时,表明我们想让PeekMessage传回程序中所有窗口的所有消息。如果要将消息从消息队列中删除,则将PeekMessage的最后一个参数设定为PM_REMOVE。如果您不希望删除消息,那么您可以将这个参数设定为PM_NOREMOVE。这就是为什么Peek_Message是「偷看」而不是「取得」的原因,它使得程序可以检查程序的队列中的下一个消息,而不实际删除它。

GetMessage不将控制传回给程序,直到从程序的消息队列中取得消息,但是PeekMessage总是立刻传回,而不论一个消息是否出现。当消息队列中有一个消息时,PeekMessage的传回值为TRUE(非0),并且将按通常方式处理消息。当队列中没有消息时,PeekMessage传回FALSE0)。

这使得我们可以改写普通的消息循环。我们可以将如下所示的循环:

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

       

{

       

    TranslateMessage (&msg) ;

       

    DispatchMessage (&msg) ;

       

}

       

return msg.wParam ;

       

替换为下面的循环:

while (TRUE)

       

{

       

    if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

       

    {

       

            if (msg.message == WM_QUIT)

       

                   break ;

       

            TranslateMessage (&msg) ;

        

            DispatchMessage (&msg) ;

       

    }

       

    else

       

    {

       

            // 完成某些工作的其它行程序

       

    }

       

}

       

return msg.wParam ;

       

注意,WM_QUIT消息被另外挑出来检查。在普通的消息循环中您不必这么作,因为如果GetMessage接收到一个WM_QUIT消息,它将传回0,但是PeekMessage用它的传回值来指示是否得到一个消息,所以需要对WM_QUIT进行检查。

如果PeekMessage的传回值为TRUE,则消息按通常方式进行处理。如果传回值为FALSE,则在将控制传回给Windows之前,还可以作一点工作(如显示另一个随机矩形)。

(尽管Windows文件上说,您不能用PeekMessage从消息队列中删除WM_PAINT消息,但是这并不是什么大不了的问题。毕竟,GetMessage并不从消息队列中删除WM_PAINT消息。从队列中删除WM_PAINT消息的唯一方法是令窗口显示区域的失效区域变得有效,这可以用ValidateRectValidateRgn或者BeginPaintEndPaint对来完成。如果您在使用PeekMessage从队列中取出WM_PAINT消息后,同平常一样处理它,那么就不会有问题了。所不能作的是使用如下所示的程序代码来清除消息队列中的所有消息:

while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) ;

       

这行叙述从消息队列中删除WM_PAINT之外的所有消息。如果队列中有一个WM_PAINT消息,程序就会永远地陷在while循环中。)

PeekMessage Windows的早期版本中比在Windows 98中要重要得多。这是因为Windows16位版本使用的是非优先权式的多任务(我将在第二十章中讨论这一点)。WindowsTerminal程序在从通讯端口接收输入后,使用一个PeekMessage循环。打印管理器程序使用这个技术来进行打印,其它的Windows打印应用程序通常都会使用一个PeekMessage循环。在Windows 98优先权式的多任务环境下,程序可以建立多个线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值