对话框管理器第六章:消息循环中的细节

在上一篇文章中,我留下了一道课后作业:找到EndManualModalDialog和模态对话框消息循环之间的细微Bug。

微妙之处在于:EndManualModalDialog会在内部设置了一些标志,但没有强制消息循环注意到该标志已实际设置。回想一下,GetMessage函数在投递性消息(Posted Message)到达消息队列之前不会返回。 如果传入的已发送消息到达,则将它们传递到相应的窗口过程,但GetMessage函数不返回。 它只是不断传递传入的已发送消息,直到投递性消息最终到达。

因此,Bug是:当你调用EndManualModalDialog时,它会设置指示模式消息循环停止运行的标志,但不会做任何事情来确保模式消息循环会检测这个标志。 在发布的消息到达之前什么都不会发生,这会导致GetMessage返回。 发送消息并重新启动while循环,此时代码最终注意到fEnded标志已设置并跳出模式消息循环。

有几种方法可以解决这个问题。比较快速的方法是:发布一条毫无意义的消息,如下图所示:

这将强制GetMessage返回,因为我们确保队列中至少有一条消息等待处理。 我们选择了 WM_NULL消息,因为它什么都不做。 我们对消息的作用不感兴趣,只对消息存在的事实感兴趣。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The dialog manager, part 6: Subtleties in message loops》

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章