科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件C#低级Windows API钩子拦截键盘输入

C#低级Windows API钩子拦截键盘输入

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文中的这个C#示例应用程序将向你展示如何基于Windows钩子API来实现在击键造成任何危害之前捕获它们。

作者:朱先忠编译 来源:天极开发 2007年11月11日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
七. 处理键盘事件

  如前面所提及,SetWindowsHookEx需要一个到被用来处理键盘事件的回调函数的指针。它期望有一个使用如下签名的函数:

LRESULT CALLBACK LowLevelKeyboardProc( int nCode,WPARAM wParam,LPARAM lParam);

  其实,建立一个函数指针的C#方法使用了一个代理,因此,向SetWindowsHookEx指出它需要的内容的第一步是使用正确的签名来声明一个代理:

private delegate IntPtr HookHandlerDelegate(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);

  然后,使用相同的签名编写一个回调方法;这个方法将包含实际上处理键盘事件的所有代码。在KeyboardHook的情况下,它检查是否击键应该被传递给其它应用程序并且接下来激发KeyIntercepted事件。下面是一个简化版本的不带有击键处理代码的情况:

private const int WM_KEYDOWN = 0x0100;
private const int WM_SYSKEYDOWN = 0x0104;
private IntPtr HookCallback(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
{
 //仅为KeyDown事件过滤wParam,否则该代码将再次执行-对于每一次击键(也就是,相应于KeyDown和KeyUp)
 //WM_SYSKEYDOWN是捕获Alt相关组合键所必需的
 if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))
 {
  //激发事件
  OnKeyIntercepted(new KeyboardHookEventArgs(lParam.vkCode, AllowKey));
  //返回一个"哑"值以捕获击键
  return (System.IntPtr)1;
 }
 //事件没有被处理,把它传递给下一个应用程序
 return CallNextHookEx(hookID, nCode, wParam, ref lParam);
}

  接下来,一个到HookCallback的参考被指派给HookHandlerDelegate的一个实例并且被传递到SetWindowsHookEx的调用,正如前一节所展示的。

  无论何时一个键盘事件发生,下列参数将被传递给HookCallBack:

  · nCode:

  根据MSDN文档,回调函数应该返回CallNextHookEx的结果,如果这个值小于零的话。正常的键盘事件将返回一个大于或等于零的nCode值。

  · wParam:

  这个值指示发生了什么类型的事件:键被按下还是松开,以及是否按下的键是一个系统键(左边或右边的Alt键)。

  · lParam:

  这是一个存储精确击键信息的结构,例如被按键的代码。在KeyboardHook中声明的这个结构如下:

private struct KBDLLHOOKSTRUCT
{
 public int vkCode;
 int scanCode;
 public int flags;
 int time;
 int dwExtraInfo;
}

  其中的这两个公共参数是在KeyboardHook中的回调方法所使用的仅有的两个参数。vkCoke返回虚拟键代码,它能够被强制转换为System.Windows.Forms.Keys以获得键名,而flags显示是否这是一个扩展键(例如,Windows Start键)或是否同时按下了Alt键。有关于Hook回调方法的完整代码展示在每一种情况下要检查哪些flags值。

  如果flags提供的信息和KBDLLHOOKSTRUCT的其它组成元素不需要,那么这个回调方法和代码的签名可以按如下进行修改:

private delegate IntPtr HookHandlerDelegate(
int nCode, IntPtr wParam, IntPtr lParam);

  在这种情况中,lParam将仅返回vkCode。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章