说说MsgWaitForMultipleObjects和队列状态
MsgWaitForMultipleObjects的危险之处在于,如果调用它的时候还有消息等待处理,这个时候调用就会挂起,因为MsgWaitForMultipleObjects只会在队列中出现一个新的事件的时候才会返回。
换句话说,让我们考虑下面的情景:
> PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)调用返回了TRUE,表明队列中有一个消息。
> 这个时候,不处理此消息,而是调用MsgWaitForMultipleObjects。
这个MsgWaitForMultipleObjects调用不会立即返回,即使这个时候,队列中确实有一个消息。因为PeekMessage已经告诉你队列中有一个消息了,而你只是故意将它忽略了。MsgWaitForMultipleObjects只会告诉你有”新”的消息,它会忽略掉你所知道的所有”旧”的消息。
下面是一个常见的错误流程:
> MsgWaitForMultipleObjects调用返回指示有一个消息。
> 这个时候,调用PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)并处理这个消息。
> 继续调用MsgWaitForMultipleObjects来等待更多的消息。
如果消息队列中有两条消息,则MsgWaitForMultipleObjects不会立即返回,因为没有新消息。但是,你故意忽略了一条旧消息。
当MsgWaitForMultipleObjects告诉你消息队列中有消息时,你必须处理所有消息,直到PeekMessage返回FALSE,表示没有更多消息。
下面的流程则没有问题:
> PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)返回了FALSE,表明消息队列中没有消息了。
> 一个新消息进入到消息队列。
> 调用MsgWaitForMultipleObjects并使用了QS_ALLPOSTMESSAGE标志。
MsgWaitForMultipleObjects调用确实会立即返回,因为传入的消息设置了“队列中有一条没人知道的新消息”标志,而QS_ALLPOSTMESSAGE匹配该标志,因此导致MsgWaitForMultipleObjects立即返回。
MsgWaitForMultipleObjectsEx函数允许你传递MWMO_INPUTAVAILABLE标志以指示它应该检查以前忽略的输入。
有了以上这些知识,请解释为什么使用以下代码观察到的这样的行为:
“有时我的程序卡住并且报告的记录比它应该报告的少。我必须摇动鼠标才能获得要更新的值。 又过了一会儿,它落后了两个,然后又落后了三个……”
总结
这些个老技术,虽然古老得尘封上了厚厚的灰尘,但是,如果你不能深刻理解,则你做的东西,始终无法”高出一品”。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《MsgWaitForMultipleObjects and the queue state》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。
- 下一篇: 说说模态化1:用户界面的模态化和代码的模态化
- 上一篇: 说说Shell动画控件的限制
相关推荐
- 深度理解:OwnerDraw和CustomDraw
- Posted on 06月10日
- 小技巧:非默认端口(21)的FTP站点的防火墙配置
- Posted on 07月01日
- IContextMenu第十一部分:组合扩展的实现
- Posted on 11月18日
- 为什么DirectX 4未曾发布?
- Posted on 10月27日
评论已关闭。