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

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

文章图片


在上一篇文章中 , 我留下了一道课后作业:找到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》
【|对话框管理器第六章:消息循环中的细节】