键盘监控的实现Ⅱ——容易产生误解的CallNextHookEx函数

简介:

 在上文“键盘监控的实现Ⅰ——Keyboard Hook API函数”中介绍了键盘的Hook API函数。

  重点就在按键消息处理函数

  Private Function KeyboardHookProc(ByVal nCode As IntegerByVal wParam As IntegerByVal lParam As IntPtr) As Integer
      Dim MyKeyboardHookStruct As KeyboardHookStruct = DirectCast(Marshal.PtrToStructure(lParam, GetType(KeyboardHookStruct)), KeyboardHookStruct)

  

  自己处理的一些代码,例如:记录、屏蔽、映射等

 

  Return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)
End Function

  

  先看看CallNextHookEx函数,从字面的理解就是调用后面一个钩子函数。若后面已经没有钩子函数呢?很多人都会错误的认为将会将消息传递给Window的消息处理函数。他们认为,消息的处理流程如下面所示:假设有4个钩子函数,分别为钩子A、钩子B、钩子C、钩子D

  物理击键

   ↓

  钩子A

   ↓

  钩子B

   ↓

  钩子C

   ↓

  钩子D

   ↓

  Window的消息处理函数

  他们认为,四个钩子函数中只要有一个返回1(非0),将会中止消息的传递。甚至在钩子函数中不调用CallNextHookEx函数也会阻止消息的传递。甚至认为,修改CallNextHookEx函数的参数就能更改按键消息的传递。

  遗憾的是,这个思路是不对的。

  你可以在钩子函数中删除CallNextHookEx函数的调用,会发现Window还是得到了按键的消息。你也可以尝试修改CallNextHookEx函数的参数,看看会有什么效果。我这样尝试后,直接报错(甚至有莫名的退出)。

  再回过头来看看CallNextHookEx函数,发现它仅仅是调用下一个钩子函数,只是在钩子函数间传递信息。

  正确的消息处理流程应该如下:还是以上面的事例为例。

  物理击键

   ↓

  钩子管理函数←→钩子A←→钩子B←→钩子C←→钩子D

   ↓

  Window消息处理函数

 

  在钩子A函数中,如果调用CallNextHookEx函数,则会将按键消息传给钩子B;如果不调用CallNextHookEx函数,则钩子B不会得到按键消息,换句话说,钩子B失效了,当然此时的钩子C和钩子D也失效了。为了钩子间和平相处,还是应该在钩子函数里添加CallNextHookEx函数的调用。

 

  再说说钩子函数的返回值的问题。在上面的事例中,钩子A的返回值决定按键消息是否丢弃。返回值0,告诉系统,消息继续传递给Window消息处理函数;返回值1(非0),告诉系统,消息将丢弃,Window消息处理函数得不到按键的消息。

 

  所以说,如果只是统计按键的信息

  在钩子函数中的最后直接调用

  Return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)

  由后面的钩子函数来决定是否丢弃该消息。(大家和平相处)

 

  如果是屏蔽按键

  在钩子函数中进行判断,满足要求后直接

  CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)  

  Return 1

  告诉系统,丢弃该消息。当然出于礼貌,在之前还是调用CallNextHookEx函数,以便其他的钩子函数处理该消息

 

  至于修改按键(映射按键),修改参数,调用CallNextHookEx函数是没有用的。因为原本的消息根本就没有修改,你改的只是传给其他钩子函数的消息。而且还非常容易出错。

  关于如何修改按键,将在后文介绍。



    本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/archive/2010/12/08/1900169.html,如需转载请自行联系原作者

相关文章
|
机器学习/深度学习 算法 数据挖掘
Python 图像处理实用指南:6~10
Python 图像处理实用指南:6~10
685 0
|
IDE 编译器 开发工具
C/C++ IDE环境 (Qt Creator visual studio等) Cmake工程不显示头文件的解决方案
C/C++ IDE环境 (Qt Creator visual studio等) Cmake工程不显示头文件的解决方案
783 0
|
10天前
|
自然语言处理 数据可视化 小程序
2025零代码平台终极对比:免费试用+系统搭建+扩展能力一网打尽
孙睿团队指出,企业数字化面临技术人力不足、开发成本高等难题,零代码平台应运而生。本文通俗解析2025年五大主流平台:LynxAI、速建云、轻栈、数流平台、万能盒,从适用场景、优缺点到实战对比,帮你选对工具,快速落地业务系统,降本增效。
|
存储 文件存储
收藏帖!FreeNAS系统硬盘损坏更换教程,重组系统恢复数据
收藏帖!FreeNAS系统硬盘损坏更换教程,重组系统恢复数据
收藏帖!FreeNAS系统硬盘损坏更换教程,重组系统恢复数据
|
Web App开发 安全 中间件
谷歌、火狐、Edge等浏览器如何使用ActiveX控件
allWebPlugin 是一款为用户提供安全、可靠且便捷的浏览器插件服务的中间件产品,支持 Chrome、Firefox、Edge 和 360 等浏览器。其 V2.0.0.20 版本支持一个页面加载多个插件,并解决了插件与浏览器之间的焦点问题。用户可通过“信息化系统 + allWebPlugin + 插件 + 浏览器”的解决方案实现 ActiveX 插件的无缝集成。下载地址见文末,安装包含详细说明。
3492 116
|
数据采集 JSON 监控
高效爬取Reddit:C#与RestSharp的完美结合
本文介绍了如何使用C#和RestSharp库,结合代理IP与多线程技术爬取Reddit数据。在数据驱动时代,Reddit作为宝贵的资料来源,其频繁更新带来了爬取挑战。通过代理服务器隐藏真实IP防止封禁,利用多线程提高并发性,文章提供代码示例展示如何实现高效爬取。关键点包括代理配置、请求头设置和数据解析统计。同时强调遵守网站条款和法律道德边界。
383 6
高效爬取Reddit:C#与RestSharp的完美结合
|
JavaScript 前端开发 索引
javascript截取两个符号之间的字符串(2):lastIndexOf匹配和正则表达式匹配
javascript截取两个符号之间的字符串(2):lastIndexOf匹配和正则表达式匹配
627 0
|
存储 缓存 监控
一文搞懂绍Servlet规范。
Servlet规范是JavaEE规范中的一种。在servlet规范中,指定【动态资源文件】开发步骤,在servlet规范中,指定Http服务器调用动态资源文件的规则,在servlet规范中,指定Http服务器管理动态资源文件实例对象规则。
|
存储 语音技术
基于单片机的银行排队叫号系统的设计
基于单片机的银行排队叫号系统的设计
370 0
Umi路由跳转传参方式都有哪些?
Umi路由跳转传参方式都有哪些
578 0