当前位置:C++技术网 > 精选软件 > 如何删除消息队列中的所有消息包括删除WM_PAINT消息

如何删除消息队列中的所有消息包括删除WM_PAINT消息

更新时间:2016-01-22 14:20:42浏览次数:1+次

    在一些应用中,我们可能需要删除消息队列里面的消息,我们能够想到的最直接的方法就是,取出消息,然后直接丢弃,不做任何处理,这样就完成了删除消息的目的。
    如果我们要将消息队列中的所有消息全部删除,那么我们可以使用while循环来实现,代码如下:
MSG msg;
while(GetMessage(&msg,NULL,0,0));
    以上代码就可以循环的取出所有的消息,实现删除。因为只是取出消息,而没有做任何处理,所以就表示将消息丢弃了。那么以上代码是如何看出删除了消息的呢?
    GetMessage函数是从消息队列中取消息的,取了消息之后,就会将消息从消息队列中移除。这样就表示了删除消息。
    然而,GetMessage函数需要取到消息后返回,否则一直等待消息的出现。那么此时就出现了问题。假如消息队列的消息取完了,也没有新消息进入队列,GetMessage就不返回了。不返回的话,就没法执行接下来的代码了。如果等待时间较长,系统会挂起程序。
    所以,我们要使用另一种实现方法,即使用函数PeekMessage。PeekMessage只是前去消息队列查看一下消息,当然也可以将消息删除。代码如下:
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE));
    PeekMessage函数的参数多了一个窗口句柄,多了一个操作选项。窗口句柄参数可以实现对某一窗口的消息进行查看。如果要查看所有的消息,传入NULL即可。最后一个选项标志,我们设置为PM_REMOVE,表示我们要移除查看的消息。
    不管消息队列有没有消息,PeekMessage都会立即返回。如果有消息,返回非零,没有消息则返回零。所以,有消息的时候,循环会继续的执行,没有消息的时候,循环结束,然后继续执行我们的代码。
    到此,似乎删除消息队列的所有消息功能已经完成。其实不然!
    WM_PAINT消息是一个特列,如果窗口存在无效区域的话,就会不断的产生WM_PAINT消息。即使你现在取出来了一个WM_PAINT消息,并丢弃了WM_PAINT。系统还会产生一个WM_PAINT消息。
    所以,要真正的消除WM_PAINT消息,就要让客户区无效区域变得有效。没有无效区域了,WM_PAINT就不会再不断的产生了。所以,对于WM_PAINT消息的删除,我们不能简单的不处理消息。我们对WM_PAINT消息做单独的处理,就是将其无效区域变成有效的就可以了。
代码如下:
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
    if(msg.message==WM_PAINT)
    {
        //使用默认的WM_PAINT处理(让无效区域变得有效)即可删除
        DispatchMessage(&msg);
    }
}

    以上这段代码只是用来删除消息队列所有消息的,不是替换消息循环的。这点需要注意一下,因为这段代码和消息循环很像。下面是一张完整的处理流程示意图:

如何删除消息队列中的所有消息包括删除WM_PAINT消息

【取消息-判断WM_PAINT-默认处理或直接丢弃】

    相信前面的介绍,足以让你看懂这个示意图了。我就不再多说了。