过滤窗口消息的时候请谨慎
有两个API,大家一定十分熟悉:GetMessage和PeekMessage。
我们可以向它们传递一个过滤器,就可以限制函数将从消息队列中检索的窗口句柄或消范围。
虽然可以使用这些过滤器,但请确保你最终要执行一次未过滤消息的调用,以便任何其他未处理的消息都可以得到妥善处理。
一个比较常见的错误是,在GetMessage消息循环中使用了一个基于窗口句柄的过滤器,例如之前我们的例子程序:
虽然在我们的例子程序中,我们只创建一个窗口,但是上面的代码仍然是不正确的。
有些人可能会问了,”这怎么可能呢?这个程序只创建了一个窗口,为什么还会有其他窗口的消息?虽然这里使用的窗口过滤器看起来有点多余,但是并没有任何害处,不是吗?”
请别忘了。很多系统服务会在后台创建窗口。举个例子,如果启用了输入编辑,则编辑器可会创建额外的窗口来辅助字符的输入。
如果你初始化COM库,则COM可能约会创建一个隐藏的窗口来辅助线程之间的封送。
另外一个例子,如果你只使用过滤的GetMessage,那么发往这些帮助窗口的消息将永远不会被处理,到时你就会摸不着头脑,想知道为什么程序在尝试执行拖放操作时偶尔会挂起。
本文的启示:确保你的消息循环最终执行未经过滤的消息处理,以便这些服务可以正常运行。
总结
要不是为了研究的目的,我想我已经很长时间没有触碰过消息循环了。
但如果你没有深入研究并理解消息循环和事件驱动,则在实现一些高级功能的时候,可能会无从下手,因为缺乏一些理论的支撑。
武林中各种流派,各种招式,但致胜之关键的是这些看不见,摸不着的所谓的内力。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The dangers of filtering window messages》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。
相关推荐
- 实战经验:鼠标在控件上悬停和离开的使用
- Posted on 05月13日
- 对话框管理器第六章:消息循环中的细节
- Posted on 08月08日
- 小技巧:解决C4996警告的一种方法
- Posted on 08月30日
- 即使运行高优先级线程,低优先线程也能运行
- Posted on 04月22日
评论已关闭。