首先要理解如下几个东西:
Windows钩子(Hook)
- 钩子的本质是一段用于处理系统信息的程序,通过系统调用,将其挂入系统。
- 钩子的种类很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先截获该消息,得到对此消息的控制权。
- 键盘钩子,是为了截取键盘消息的。
- 全局钩子,可以捕获Windows平台下任意窗口上的键盘操作。
- Hooks Overview(Windows)
http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644959(v=vs.85).aspx
系统钩子和DLL
- 如果需要捕获在任意窗口上的键盘输入,需要采用全局钩子以便拦截整个系统的消息,而全局钩子函数必须以DLL为载体进行封装.
A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate DLL module.
Note You should use global hooks only for debugging purposes; otherwise, you should avoid them. Global hooks hurt system performance and cause conflicts with other
applications that implement the same type of global hook.
Hook Types
- Each type of hook enables an application to monitor a different aspect of the system's message-handling mechanism.
- WH_KEYBOARD_LL
The WH_KEYBOARD_LL hook enables you to monitor keyboard input events about to be posted in a thread input queue.
For more information, see the LowLevelKeyboardProc callback function.
- WH_KEYBOARD
The WH_KEYBOARD hook enables an application to monitor message traffic for WM_KEYDOWN and WM_KEYUP messages about to be returned by the GetMessage or PeekMessage
function. You can use the WH_KEYBOARD hook to monitor keyboard input posted to a message queue.
For more information, see the KeyboardProc callback function.
Windows 系统钩子的安装
- 调用SDK中的API函数SetWindowsHookEx()来安装钩子函数.
HHOOK SetWindowsHookEx(
int idHook, //钩子的类型. 如WH_MOUSE, WH_KEYBOARD, WH_GETMESSAGE 等. 键盘操作中设定为WH_KEYBOARD.
HOOKPROC lpfn, //钩子函数的入口地址. 当钩子钩到任何消息后便调用这个函数。不管系统的哪个窗口有键盘输入马上引起LauncherHoook动作.
HINSTANCE hMode, //钩子函数所在模块的句柄. 可以简单的设定为本应用程序的实例句柄。
DWORD dwThreadId //钩子相关函数的ID. 用以指定想让钩子去钩哪个线程,为0则拦截整个系统的消息。键盘操作中需要为全局钩子,即设置为0.
);
键盘基础:
用键盘当作输入设备,每当用户按下或释放某一个键时,会产生一个中断,该中断激活键盘驱动程序KEYBOARD.DRV来对键盘中断进行处理。KEYBOARD.DRV程序会根据用户的不同操作进行编码,然后调用Windows用户模块USER.EXE生成键盘消息,并将该消息发送到消息队列中等候处理。
虚拟码和扫描码
- Virtul-Key Code
虚拟键码是系统规定的,对完成某个功能的键(这个键对某个特定的系统可能根本不存在)的一种与硬件无关的编码。
- Hardware Scan Code.
硬件扫描码对应着键盘上的不同键,每一个键被按下或释放时,都会产生一个唯一的扫描码作为本身的标识。它是与硬件相关的(键盘驱动产生),每个键值是唯一的。
扫描码依赖于具体的硬件设备,即当相同的键被按下或释放时,在不同的机器上可能产生不同的扫描码。
- 程序中通常使用由Windows系统定义的与具体设备无关的虚拟码。在击键产生扫描码的同时,键盘驱动程序KEYBOARD.DRV截取键的扫描码,然后将其翻译成对应的虚拟码,再将扫描码和虚拟码一齐编码形成键盘消息。所以,最后发送到消息队列的键盘消息中,既包含了扫描码又包含了虚拟码。
键盘事件
当用户按键盘键时,Windows 窗体提供两个事件
-KeyDown 事件发生一次
-KeyPress 事件,当用户按住同一个键时,该事件可以发生多次。
而当用户松开键盘键时,Windows 窗体提供一个事件(当用户松开物理键时将引发此事件)
-当用户松开键时,KeyUp 事件发生一次。
当用户按键时,Windows 窗体根据键盘消息指定的是字符键还是物理键来确定要引发的事件.
KeyDown 事件
- 当用户按物理键时将引发此事件。
- KeyDown 的处理程序接收:
.一个 KeyEventArgs 参数,它提供 KeyCode 属性(它指定一个物理键盘按钮)。
.Modifiers 属性(Shift、Ctrl 或 Alt)。
.KeyData 属性(它组合键代码和修改键)。KeyEventArgs 参数还提供:
.Handled 属性,可以设置该属性以防止基础控件接收键。
.SuppressKeyPress 属性,它可以用来抑制该键击的 KeyPress 和 KeyUp 事件。
KeyPress 事件
- 当所按的键产生字符时将引发此事件。例如,当用户按 Shift 和小写的“a”键时,将产生大写字母“A”字符。
- KeyPress 在 KeyDown 之后引发。
- KeyPress 的处理程序接收:
.一个 KeyPressEventArgs 参数,它包含所按键的字符代码。此字符代码对于字符键和修改键的每个组合都是唯一的。
例如,“A”键将生成:字符代码 65(如果与 Shift 键一起按下)
或 Caps Lock 键 97(如果只按下它一个键),
和 1(如果它与 Ctrl 键一起按下)。
KeyUp 事件
- 当用户松开物理键时将引发此事件。
- KeyUp 的处理程序接收:
.KeyEventArgs 参数:它提供 KeyCode 属性(指定一个物理键盘按钮)。
.Modifiers 属性(Shift、Ctrl 或 Alt)。
.KeyData 属性(它组合键代码和修改键)。
KeyEventArgs类
- 为KeyDown 或 KeyUp事件提供数据。
- 继承层次关系: System.Object -> System.EventArgs -> System.Windows.Forms.KeyEventArg
- 成员和成员函数:
.构造函数: KeyEventArgs: 初始化 KeyEventArgs 类的新实例。
.属性:
Alt: 获取一个值,该值指示是否曾按下 Alt 键。Boolean型.
Control: 获取一个值,该值指示是否曾按下 Ctrl 键。
Handled: 获取或设置一个值,该值指示是否处理过此事件.
KeyCode: 获取 KeyDown 或 KeyUp 时按下键盘的 Keys 的枚举( 类型:System.Windows.Forms.Keys)
KeyData: 获取 KeyDown 或 KeyUp 事件的键数据。类型:System.Windows.Forms.Keys ,
一个 Keys,表示按下的键的键代码以及修饰符标志(指示同时按下的 Ctrl、Shift 和 Alt 键的组合)。
KeyValue:实际上等于 KeyCode, KeyCode是枚举,KeyValue是枚举对应的Integer值 (类型:System.Int32 )
Modifiers: 获取 KeyDown 或 KeyUp 事件的修饰符标志。这些标志指示按下的 Ctrl、Shift 和 Alt 键的组合。
Shift: 获取一个值,该值指示是否曾按下 Shift 键。
SuppressKeyPress: 获取或设置一个值,该值指示键事件是否应传递到基础控件。
.方法:
(略)
Keyboard Scan Code (硬件扫描码)
- 当按下一键式,产生mark码,产生一次IRQ1中断。放开键时,产生break码,产生一次IRQ1中断.
- break 是 mark 码的 bit7 置 1 得来,也就是: break = mark + 0x80
- 一个基本按键的扫描码由3个字节组成,接通扫描码(1Byte)和断开扫描码(2Byte)
其中第一和第二个字节相同。中间字节是断开标志F0H.
例如B键的接通扫描码是32H, 断开扫描码是F0H 32H 。
- 扩展键(功能键,控制键)的扫描码有5个字节组成,在接通/断开扫描码前多了一个固定字符E0H.
例如HOME键的接通扫描码是E0H 70H ,断开扫描码是 E0H F0H 70H.
- 特殊键:PrintScreen 接通扫描码:E0H 12H E0H 7CH; 断开扫描码 E0H F0H 7CH E0H F0H 77H .
还有个是Pause/Break 键 :E1 1D 45 E1 9D C5
参考:http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
http://msdn.microsoft.com/en-us/library/ms645575(v=VS.85).aspx
底层键盘钩子 : http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms644967(v=vs.85).aspx
分享到:
相关推荐
C#键盘鼠标钩子类
C# 调取vc dll编写的全局钩子 监控键盘,鼠标事件,并显示到winform窗口。
既可以支持中文,又可以支持英文。非常好用。
VC 监测键盘上每一按键的变化,应用了HOOK,键盘钩子,运行截图如上所示,当敲击键盘上的任一个按键时,程序都会检测到,并弹出窗口,告诉用户按下的是哪个键。
键盘事件 ,钩子 获取键盘事件vc# 获取键盘事件vc#
全局底层键盘鼠标钩子,导出接口已添加,直接使用。win10 + VS2013 编译。有需要可下载。
VC6.0工程,用钩子实现记录用户键盘、鼠标操作并重现 运行程序,选择Record,再输入一些文字等操作,再选择stop,再重现刚才操作。
VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写...
键盘钩子,截获键盘信息。 Kugou7+UI 界面设计。学习界面的好实例,强烈推荐。 自绘button 如题。 自绘MENU 如题。 自绘tab 如题。 自绘Tree 如题。 自绘按钮button源代码 如题。 自绘编辑框 如题。 自绘...
VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写...
VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写...
VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写...
VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写...