zoukankan      html  css  js  c++  java
  • 键盘监控的实现Ⅱ——容易产生误解的CallNextHookEx函数

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

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

      Private Function KeyboardHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal 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函数是没有用的。因为原本的消息根本就没有修改,你改的只是传给其他钩子函数的消息。而且还非常容易出错。

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

      

  • 相关阅读:
    ClickOne :添加ClickOnce程序的快捷方式
    C#: 通过html调用WinForm 。。。。。
    JQuery:常用方法一览
    Jquery:Ajax解析XML数据(同步及异步调用)
    系统管理:服务器超级隐藏账户的建立与检测大全[转载]
    Jquery :动态给Table指定行或尾行插入tr和相关,遍历页面所有控件获取id
    .Net : webBrowser弹出新页面,在当前Form窗体打开,可设置屏蔽当前网页的js错误。。。。
    Visual Studio 设置:包括根据不同类型的开发活动对集成开发环境 (IDE) 所做的各种自定义设置
    VB.Net : ApplicationEvents类中,创建主程序的快捷方式 , 捕获程序未Try的错误及抛出相关的类和方法名 , 是否联机等相关。。
    [转载]JavaScript 图片预览效果
  • 原文地址:https://www.cnblogs.com/grenet/p/1900169.html
Copyright © 2011-2022 走看看