当前栏目
使用消息过滤器找回丢失的线程消息
线程消息在模态循环中会丢失,因为消息分发器(Message Dispatcher)不知道应该如何分发此消息。但是,如果模态循环能支持的话,我们有一种方法可以在它们消失之前看到它们。
WH_MSGFILTER 消息钩子可以用来接收传递给 CallMsgFilter 函数的消息。幸运的是,窗口管理器中的所有模态循环都使用 CallMsgFilter 来允许线程在线程消息丢失之前捕获它们。 因此,这为我们提供了一种方法,可以在消息通过模态循环时对它们进行监控。
让我们在上次编写的程序中添加一个消息过滤器,看看消息是如何通过消息过滤器的。但是,请注意,这是不是解决之前问题的正确方法。 我们在上一篇文章中说明了正确的解决方法。我用错误的方式来说明消息过滤器,主要是因为它没有被开发人员很好地理解。 (例如,消息过滤器的正当理由是,阻止菜单循环看到某些输入消息。)
从上一个程序开始,在我们将 PostThreadMessage 更改为 PostMessage 之前,然后进行以下更改:
在这里,我们在线程上安装了一个消息过滤器钩子,以便我们可以在消息通过模态循环时显示它们。 code 参数告诉我们什么类型的模态循环检索到了消息; 我们在这里忽略它,因为我们想对所有模态循环进行过滤。
运行这个程序并观察蜂鸣器声不再丢失,因为我们的消息过滤器有机会看到它们并对它们做出反应。
消息过滤器技巧依赖于所有模态循环,它们在分发它们之前,通过消息过滤器发送它们检索到的消息。 如果你正在编写要进入库的代码,并且你有一个模态循环,那么你也应该在分发消息之前调用消息过滤器,以防你的代码库的使用者想要对消息做一些事情。
MSGF_MYLIBRARY 可以是一个任意值,你可以选择并记录在库的头文件中。 在 commctrl.h 头文件中,我们会看到这样的示例代码:
上面这些是由外壳(Shell)公共控件库中的模式循环调用的消息过滤器。
你可能会问一个问题,“为什么使用消息过滤器挂钩而不是 GetMessage 挂钩?”
消息过滤器钩子比 GetMessage 钩子占用资源更少,因为它们仅在请求时调用,与 GetMessage 钩子相反,GetMessage 钩子为每个检索到的消息调用。 消息过滤器钩子还会告诉你哪个模态循环正在执行过滤,这样就可以调整相应的动作。
消息过滤器钩子的缺点是所有模式循环都需要记住调用 CallMsgFilter,将其作为其调度循环的一部分。但这个,应该问题不大,一句代码的事儿。
总结
早在研究 VNC 代码的那个年代,我就知道 有Windows 消息钩子这回事儿了。奈何,因为当时水平不济,一直没能透彻理解它并真正地写出一些代码,也就搁置了。通过今天的文章,我还是没太能完全理解它,但是,这有助于提醒我:Windows 基础设施中有很多需要我去发现的瑰宝。
相关文章
- JDK中内嵌JS引擎介绍及使用
- 49195,npm最后的疯狂?盘点10款最有前途JavaScript构建工具
- 译文:5个增强Node.js应用程序增强功能
- 4个例子,吃透 JavaScript 实现的二叉搜索树 BST
- Vue中使用XML和JSON格式互转插件
- JDK中Jshell简单使用(JDK9版本以上或者JDK9版本)
- shiro中的JSP标签支持
- Java技术点-json转对象,对象转json
- SpringBoot+SpringDataJpa @Query之 JPQL使用书写模板(模糊查询and条件查询)
- Spring Boot中的Freemarker模版引擎引用css和js的正确姿势
- Node.js解压版的环境配置及相关常用命令
- JSP学习笔记(6)—— 自定义MVC框架
- JSP学习笔记(5)——Servlet、监听器、过滤器、MVC模式介绍
- Jsp学习笔记(4)——分页查询
- APIJSON简单使用
- JSP学习笔记(3)——JSTL 标签库
- JSP学习笔记(1)——Jsp指令、动作元素和内置对象
- JavaScript ES6 Promise对象
- Web前端——JavaScript扩展补充
- Web前端——表单提交和Js添加选项