原文:WPF 利用键盘钩子来捕获键盘,做一些不为人知的事情...完整实例

键盘钩子是一种可以监控键盘操作的指令。

看到这句话是不是觉得其实键盘钩子可以做很多事情.

场景

当你的程序需要一个全局的快捷键时,可以考虑使用键盘钩子,如大家常用qq的截图快捷键,那么在WPF里怎么去实现呢?

当然不是直接在Window窗体里面去注册KeyDown、KeyUp,这样只有在程序是焦点的情况下才能触发,

我们这里要做的更为强大,即在非焦点下去获取到键盘的事件(要偷偷记录女朋友键盘记录的滚粗,当然我是在开玩笑,程序猿哪里有女朋友,我们只有男朋友(⊙0⊙))

实现

首先我们需要用到这么几个WinAPI

//安装钩子的函数

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, intthreadId);//卸下钩子的函数

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(intidHook);//下一个钩挂的函数

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

大致的逻辑为:

安装键盘钩子,然后通过委托来处理获取到的键盘消息

整理为两个类(winapi[Win32Api.cs]类和键盘钩子[KeyboardHook.cs]类)如下

public classWin32Api

{public const int WM_KEYDOWN = 0x100;public const int WM_KEYUP = 0x101;public const int WM_SYSKEYDOWN = 0x104;public const int WM_SYSKEYUP = 0x105;public const int WH_KEYBOARD_LL = 13;

[StructLayout(LayoutKind.Sequential)]//声明键盘钩子的封送结构类型

public classKeyboardHookStruct

{public int vkCode; //表示一个在1到254间的虚似键盘码

public int scanCode; //表示硬件扫描码

public intflags;public inttime;public intdwExtraInfo;

}public delegate int HookProc(intnCode, Int32 wParam, IntPtr lParam);//安装钩子的函数

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, intthreadId);//卸下钩子的函数

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(intidHook);//下一个钩挂的函数

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, intnCode, Int32 wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]public static extern IntPtr GetModuleHandle(stringlpModuleName);

}

public classKeyboardHook

{inthHook;

Win32Api.HookProc KeyboardHookDelegate;///

///安装键盘钩子///

public voidSetHook()

{

KeyboardHookDelegate= newWin32Api.HookProc(KeyboardHookProc);

ProcessModule cModule=Process.GetCurrentProcess().MainModule;var mh =Win32Api.GetModuleHandle(cModule.ModuleName);

hHook= Win32Api.SetWindowsHookEx(Win32Api.WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);

}///

///卸载键盘钩子///

public voidUnHook()

{

Win32Api.UnhookWindowsHookEx(hHook);

}///

///获取键盘消息///

///

///

///

///

private int KeyboardHookProc(intnCode, Int32 wParam, IntPtr lParam)

{//如果该消息被丢弃(nCode<0

if (nCode >= 0)

{

Win32Api.KeyboardHookStruct KeyDataFromHook= (Win32Api.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.KeyboardHookStruct));int keyData =KeyDataFromHook.vkCode;//WM_KEYDOWN和WM_SYSKEYDOWN消息,将会引发OnKeyDownEvent事件

if (OnKeyDownEvent != null && (wParam == Win32Api.WM_KEYDOWN || wParam ==Win32Api.WM_SYSKEYDOWN))

{//此处触发键盘按下事件//keyData为按下键盘的值,对应 虚拟码

}//WM_KEYUP和WM_SYSKEYUP消息,将引发OnKeyUpEvent事件

if (OnKeyUpEvent != null && (wParam == Win32Api.WM_KEYUP || wParam ==Win32Api.WM_SYSKEYUP))

{//此处触发键盘抬起事件

}

}returnWin32Api.CallNextHookEx(hHook, nCode, wParam, lParam);

}

}

当时拿在虚拟码的时候其实我是拒绝的,因为在接下来我竟然不知道要对这些虚拟码做什么处理,难道要一个一个转换才能在WPF里进一步的去判断按下的是什么键?

最后经博客园告知,在System.Windows.Input命名空间下其实已经封装了转换的方法

namespaceSystem.Windows.Input

{//摘要://提供在 Win32 虚拟键和 WPFSystem.Windows.Input.Key 枚举之间进行转换的静态方法。

public static classKeyInterop

{//摘要://将 Win32 虚拟键转换为 WPFSystem.Windows.Input.Key。//

//参数://virtualKey://要转换的虚拟键。//

//返回结果://WPF 键。

public static Key KeyFromVirtualKey(intvirtualKey);//

//摘要://将 WPFSystem.Windows.Input.Key 转换为 Win32 虚拟键。//

//参数://key://要转换的 WPF。//

//返回结果://Win32 虚拟键。

public static intVirtualKeyFromKey(Key key);

}

}

结果

于是我们开开心心的拿到了基友的键盘操作记录

KeyInterop.KeyFromVirtualKey(KeyData)

nono,我只是拿来做了一个钢琴键盘

代码已贴,恕不给基友另行提供Demo

python 键盘钩子_WPF 利用键盘钩子来捕获键盘,做一些不为人知的事情...完整实例...相关推荐

  1. WPF 利用键盘钩子来捕获键盘,做一些不为人知的事情...完整实例

    原文:WPF 利用键盘钩子来捕获键盘,做一些不为人知的事情...完整实例 键盘钩子是一种可以监控键盘操作的指令. 看到这句话是不是觉得其实键盘钩子可以做很多事情. 场景 当你的程序需要一个全局的快捷键 ...

  2. python字典通讯录_Python利用字典将两个通讯录文本合并为一个文本实例

    本文实例主要实现的是利用字典将两个通讯录文本合并为一个文本,具体代码如下: def main(): ftele1=open("d:\TeleAddressBook.txt",&qu ...

  3. 基于python的图书管理系统测试步骤_Django admin实现图书管理系统菜鸟级教程完整实例...

    Django 有着强大而又及其易用的admin后台,在这里,你可以轻松实现复杂代码实现的功能,如搜索,筛选,分页,题目可编辑,多选框. 简单到,一行代码就可以实现一个功能,而且模块之间耦合得相当完美. ...

  4. python keyboard库_python利用 keyboard 库记录键盘事件

    今天也不知道是想了什么,突然就想要试试看我有效击键时的手速到底有多快.为此,需要记录下来击键的记录.于是找到了 Python 的 keyboard 库. 安装非常简单,只需执行 pip install ...

  5. 计算机病毒对消息钩子的利用与对抗

    作 者: dncwbc 时 间: 2011-10-07,23:57:15 链 接: http://bbs.pediy.com/showthread.php?t=141059 一.消息钩子的概念     ...

  6. 一行 Python 实现并行化 -- 日常多线程操作的新思路 - 左手键盘,右手书 - SegmentFault...

    一行 Python 实现并行化 -- 日常多线程操作的新思路 - 左手键盘,右手书 - SegmentFault

  7. python 写游戏好简单啊,我用键盘可以随意控制角色了【python 游戏实战 04】

    前言 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖了新手在学习中的一般问题.此系列将会持续更新,包括别的语言以及实战都将使用对话的方式进行教学,基础编程语言教学适用于零基础小白,之后实战课 ...

  8. pythonselenium教程模拟鼠标和键盘_【02篇】python+selenium实现Web自动化:鼠标操作和键盘操作!...

    一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第二篇博 ...

  9. C++关于利用_kbhit()函数持续获取键盘输入的一点心得。

    #C++关于利用_kbhit()函数持续获取键盘输入的一点心得. 小白路过想写个贪吃蛇玩玩,当用链表把贪吃蛇结构连起来后自然就想到了移动控制的问题.写来写去代码总是出错,贪吃蛇只有一直按着方向键才能移 ...

最新文章

  1. Android配置----Android开发环境搭建
  2. CCS V5 创建工程和配置软件仿真
  3. Linux内存(手动释放cache)
  4. 20201202 《计算感知》武老师 第2节课 笔记
  5. 作为一名 ABAP 资深顾问,下一步可以选择哪一门 SAP 技术作为主攻方向?
  6. uniapp 获取到js文件var一个变量怎么获取到这个变量值_浅析Js中const,let,var的区别及作用域...
  7. c语言乘法表 m*(9-i),C语言做九九乘法表.doc
  8. 使用函数统计指定c语言,浙大版《C语言程序设计(第3版)》题目集 习题5-5 使用函数统计指定数字的个数...
  9. go语言与php优势,go语言有什么优点?
  10. CSS骚操作之表单验证功能的实现代码
  11. [工具库]JOXMLBuilder工具类——一键把多个bean对象数据转换为XML格式数据
  12. github创建maven项目过程
  13. xcode快捷创建控件
  14. 【BZOJ】1270 [BeijingWc2008]雷涛的小猫
  15. PHP中的数组(集合)
  16. 【机器学习算法实现】主成分分析(PCA)——基于python+numpy
  17. 供应链运作参考模型(SCOR):一种用于改善供应链管理的模型
  18. 开源硬件USB抓包及协议分析工具分享
  19. Mysql高级-day02
  20. 《JavaSE-第十四章》之文件(一)

热门文章

  1. C++上机实验2-1标准体重
  2. svn提交忽略target目录
  3. linux svn怎么提交代码,linux提交代码到svn服务器
  4. Unity访问Access数据库
  5. 汇编语言实验四-《汇编语言-王爽老师》
  6. Oracle 正则表达式详解(regexp_substr、regexp_instr、regexp_replace、regexp_like)
  7. matlab2021a安装包
  8. 基于CMake的交叉编译工具链配置问题总结
  9. 谷歌验证码,国内各种验证码识别
  10. 虚拟机无法ping通外网