-
C#教程之基于C#实现的HOOK键盘钩子实例代码
本文所述为基于C#实现的HOOK实例,该实例可用来屏蔽系统热键。程序主要实现了安装钩子、传递钩子、卸载钩子等功能。在传递钩子中:
<param name="pHookHandle">是您自己的钩子函数的句柄。用该句柄可以遍历钩子链</param>
< param name="nCode">把传入的参数简单传给CallNextHookEx即可</param>
< param name="wParam">把传入的参数简单传给CallNextHookEx即可</param>,
在HOOK类中定义了一些私有变量:键盘钩子句柄、键盘钩子委托实例、底层的钩子变量等。在钩子捕获消息后,对消息进行处理。
具体实现HOOK代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Reflection; using System.IO; namespace 设置和屏蔽系统热键 { class HOOK { #region 私有变量 private IntPtr m_pKeyboardHook = IntPtr.Zero; /// 键盘钩子句柄 public delegate int HookProc( int nCode, Int32 wParam, IntPtr lParam); /// 钩子委托声明 private HookProc m_KeyboardHookProcedure; /// 键盘钩子委托实例 public const int idHook = 13; /// 底层的钩子变量 [DllImport( "user32.dll" , CallingConvention = CallingConvention.StdCall)] public static extern IntPtr SetWindowsHookEx( int idHook, HookProc lpfn, IntPtr pInstance, int threadId); /// 安装钩子 [DllImport( "user32.dll" , CallingConvention = CallingConvention.StdCall)] /// 卸载钩子 public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle); /// 传递钩子 /// <param name="pHookHandle">是您自己的钩子函数的句柄。用该句柄可以遍历钩子链</param> /// <param name="nCode">把传入的参数简单传给CallNextHookEx即可</param> /// <param name="wParam">把传入的参数简单传给CallNextHookEx即可</param> /// <param name="lParam"></param> /// <returns></returns> [DllImport( "user32.dll" , CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(IntPtr pHookHandle, int nCode, Int32 wParam, IntPtr lParam); [StructLayout(LayoutKind.Sequential)] public struct KeyMSG { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } protected const int WM_QUERYENDSESSION = 0x0011; protected const int WM_KEYDOWN = 0x100; protected const int WM_KEYUP = 0x101; protected const int WM_SYSKEYDOWN = 0x104; protected const int WM_SYSKEYUP = 0x105; protected const byte VK_SHIFT = 0x10; protected const byte VK_CAPITAL = 0x14; protected const byte VK_NUMLOCK = 0x90; protected const byte VK_LSHIFT = 0xA0; protected const byte VK_RSHIFT = 0xA1; protected const int VK_LWIN = 91; protected const int VK_RWIN = 92; protected const byte VK_LCONTROL = 0xA2; protected const byte VK_RCONTROL = 0x3; protected const byte VK_LALT = 0xA4; protected const byte VK_RALT = 0xA5; protected const byte LLKHF_ALTDOWN = 0x20; public bool Porwer = true ; //是否屏蔽Porwer键 public static int pp = 0; //热键的返回值 public static bool isSet = false ; //是否设置屏蔽热键,false为设置屏蔽的热键 public static bool isHotkey = false ; public static bool isInstall = false ; //是否安装钩子,true为安装 #endregion #region 事件的声明 public event KeyEventHandler KeyDown; //键盘按下事件 public event KeyEventHandler KeyUp; //键盘松开事件 public event KeyPressEventHandler KeyPress; //键盘单击事件 #endregion #region 方法 /// <summary> /// 钩子捕获消息后,对消息进行处理 /// </summary> /// <param nCode="int">标识,键盘是否操作</param> /// <param wParam="int">键盘的操作值</param> /// <param lParam="IntPtr">指针</param> private int KeyboardHookProc( int nCode, int wParam, IntPtr lParam) { if (nCode > -1 && (KeyDown != null || KeyUp != null || KeyPress != null )) { KeyMSG keyboardHookStruct = (KeyMSG)Marshal.PtrToStructure(lParam, typeof (KeyMSG)); //获取钩子的相关信息 KeyEventArgs e = new KeyEventArgs((Keys)(keyboardHookStruct.vkCode)); //获取KeyEventArgs事件的相磁信息 switch (wParam) { case WM_KEYDOWN: //键盘按下操作 case WM_SYSKEYDOWN: if (KeyDown != null ) //如果加载了当前事件 { KeyDown( this , e); //调用该事件 } break ; case WM_KEYUP: //键盘松开操作 case WM_SYSKEYUP: if (KeyUp != null ) //如果加载了当前事件 { KeyUp( this , e); //调用该事件 } break ; } } return pp; //是否屏蔽当前热键,1为屏蔽,2为执行 } #endregion #region 安装、卸载钩子 /// <summary> /// 安装钩子 /// </summary> /// <returns>是否安装成功</returns> public bool Start() { IntPtr pInstance = (IntPtr)4194304; //钩子所在实例的句柄 if ( this .m_pKeyboardHook == IntPtr.Zero) //如果键盘的句柄为空 { this .m_KeyboardHookProcedure = new HookProc(KeyboardHookProc); //声明一个托管钩子 this .m_pKeyboardHook = SetWindowsHookEx(idHook, m_KeyboardHookProcedure, pInstance, 0); //安装钩子 if ( this .m_pKeyboardHook == IntPtr.Zero) //如果安装失败 { this .Stop(); //卸载钩子 return false ; } } isInstall = true ; //安装了钩子 return true ; } /// <summary> /// 卸载钩子 /// </summary> /// <returns>是否卸载成功</returns> public bool Stop() { if (isInstall == false ) //如果没有安装钩子 { return true ; } bool result = true ; if ( this .m_pKeyboardHook != IntPtr.Zero) //如果安装了钩子 { result = (UnhookWindowsHookEx( this .m_pKeyboardHook) && result); //卸载钩子 this .m_pKeyboardHook = IntPtr.Zero; //清空键盘的钩子句柄 } return result; } #endregion 公共方法 } } |
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式