简介:由三个文件构成Pinvo.cs、KeyboardHook.cs、MouseHook.cs
Pinvo.cs 是KeyboardHook与MouseHook需要的一些常量消息的定义
KeyboardHook 是实现的一个WH_KEYBOARD_LL类型的全局键盘钩子(SetWindowsHookExA函数最后一个参数threadId=0)
MouseHook 是实现的一个WH_MOUSE_LL类型的全局鼠标按键钩子(SetWindowsHookExA函数最后一个参数threadId=0)
Pinvo
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace KMHook 8 { 9 public class HookType 10 { 11 public const int WH_CALLWNDPROC = 4; 12 public const int WH_KEYBOARD_LL = 13; 13 public const int WH_MOUSE_LL = 14; 14 } 15 16 public class Messages 17 { 18 public const int WM_MOUSEHOVER = 0x02A1; 19 public const int WM_MOUSELEAVE = 0x02A3; 20 public const int WM_DEVICECHANGE = 0x0219; 21 public const int WM_DDE_FIRST = 0x03E0; 22 public const int WM_BB_ENABLE = 0x00000001; 23 public const int WM_BB_BLURREGION = 0x00000002; 24 public const int WM_BB_TRANSITIONONMAXIMIZED = 0x00000004; 25 public const int WM_CLOAKED_APP = 0x00000001; 26 public const int WM_CLOAKED_SHELL = 0x00000002; 27 public const int WM_CLOAKED_INHERITED = 0x00000004; 28 public const int WM_TNP_RECTDESTINATION = 0x00000001; 29 public const int WM_TNP_RECTSOURCE = 0x00000002; 30 public const int WM_TNP_OPACITY = 0x00000004; 31 public const int WM_TNP_VISIBLE = 0x00000008; 32 public const int WM_TNP_SOURCECLIENTAREAONLY = 0x00000010; 33 public const int WM_SIT_DISPLAYFRAME = 0x00000001; 34 public const int WM_HELP = 0x0011; 35 public const int WM_IME_REPORT = 0x0280; 36 public const int WM_CONVERTREQUESTEX = 0x0109; 37 public const int WM_WNT_CONVERTREQUESTEX = 0x0109; 38 public const int WM_CONVERTREQUEST = 0x010A; 39 public const int WM_CONVERTRESULT = 0x010B; 40 public const int WM_INTERIM = 0x010C; 41 public const int WM_IMEKEYDOWN = 0x290; 42 public const int WM_IMEKEYUP = 0x291; 43 public const int WM_RASDIALEVENT = 0xCCCD; 44 public const int WM_CONTEXTMENU = 0x007B; 45 public const int WM_UNICHAR = 0x0109; 46 public const int WM_PRINTCLIENT = 0x0318; 47 public const int WM_NOTIFY = 0x004E; 48 public const int WM_HANDLED_MASK = 0x1; 49 public const int WM_TABLET_DEFBASE = 0x02C0; 50 public const int WM_TABLET_MAXOFFSET = 0x20; 51 public const int WM_NULL = 0x0000; 52 public const int WM_CREATE = 0x0001; 53 public const int WM_DESTROY = 0x0002; 54 public const int WM_MOVE = 0x0003; 55 public const int WM_SIZE = 0x0005; 56 public const int WM_ACTIVATE = 0x0006; 57 public const int WM_SETFOCUS = 0x0007; 58 public const int WM_KILLFOCUS = 0x0008; 59 public const int WM_ENABLE = 0x000A; 60 public const int WM_SETREDRAW = 0x000B; 61 public const int WM_SETTEXT = 0x000C; 62 public const int WM_GETTEXT = 0x000D; 63 public const int WM_GETTEXTLENGTH = 0x000E; 64 public const int WM_PAINT = 0x000F; 65 public const int WM_CLOSE = 0x0010; 66 public const int WM_QUERYENDSESSION = 0x0011; 67 public const int WM_QUERYOPEN = 0x0013; 68 public const int WM_ENDSESSION = 0x0016; 69 public const int WM_QUIT = 0x0012; 70 public const int WM_ERASEBKGND = 0x0014; 71 public const int WM_SYSCOLORCHANGE = 0x0015; 72 public const int WM_SHOWWINDOW = 0x0018; 73 public const int WM_WININICHANGE = 0x001A; 74 public const int WM_DEVMODECHANGE = 0x001B; 75 public const int WM_ACTIVATEAPP = 0x001C; 76 public const int WM_FONTCHANGE = 0x001D; 77 public const int WM_TIMECHANGE = 0x001E; 78 public const int WM_CANCELMODE = 0x001F; 79 public const int WM_SETCURSOR = 0x0020; 80 public const int WM_MOUSEACTIVATE = 0x0021; 81 public const int WM_CHILDACTIVATE = 0x0022; 82 public const int WM_QUEUESYNC = 0x0023; 83 public const int WM_GETMINMAXINFO = 0x0024; 84 public const int WM_PAINTICON = 0x0026; 85 public const int WM_ICONERASEBKGND = 0x0027; 86 public const int WM_NEXTDLGCTL = 0x0028; 87 public const int WM_SPOOLERSTATUS = 0x002A; 88 public const int WM_DRAWITEM = 0x002B; 89 public const int WM_MEASUREITEM = 0x002C; 90 public const int WM_DELETEITEM = 0x002D; 91 public const int WM_VKEYTOITEM = 0x002E; 92 public const int WM_CHARTOITEM = 0x002F; 93 public const int WM_SETFONT = 0x0030; 94 public const int WM_GETFONT = 0x0031; 95 public const int WM_SETHOTKEY = 0x0032; 96 public const int WM_GETHOTKEY = 0x0033; 97 public const int WM_QUERYDRAGICON = 0x0037; 98 public const int WM_COMPAREITEM = 0x0039; 99 public const int WM_GETOBJECT = 0x003D; 100 public const int WM_COMPACTING = 0x0041; 101 public const int WM_COMMNOTIFY = 0x0044; 102 public const int WM_WINDOWPOSCHANGING = 0x0046; 103 public const int WM_WINDOWPOSCHANGED = 0x0047; 104 public const int WM_POWER = 0x0048; 105 public const int WM_COPYDATA = 0x004A; 106 public const int WM_CANCELJOURNAL = 0x004B; 107 public const int WM_INPUTLANGCHANGEREQUEST = 0x0050; 108 public const int WM_INPUTLANGCHANGE = 0x0051; 109 public const int WM_TCARD = 0x0052; 110 public const int WM_USERCHANGED = 0x0054; 111 public const int WM_NOTIFYFORMAT = 0x0055; 112 public const int WM_STYLECHANGING = 0x007C; 113 public const int WM_STYLECHANGED = 0x007D; 114 public const int WM_DISPLAYCHANGE = 0x007E; 115 public const int WM_GETICON = 0x007F; 116 public const int WM_SETICON = 0x0080; 117 public const int WM_NCCREATE = 0x0081; 118 public const int WM_NCDESTROY = 0x0082; 119 public const int WM_NCCALCSIZE = 0x0083; 120 public const int WM_NCHITTEST = 0x0084; 121 public const int WM_NCPAINT = 0x0085; 122 public const int WM_NCACTIVATE = 0x0086; 123 public const int WM_GETDLGCODE = 0x0087; 124 public const int WM_SYNCPAINT = 0x0088; 125 public const int WM_NCMOUSEMOVE = 0x00A0; 126 public const int WM_NCLBUTTONDOWN = 0x00A1; 127 public const int WM_NCLBUTTONUP = 0x00A2; 128 public const int WM_NCLBUTTONDBLCLK = 0x00A3; 129 public const int WM_NCRBUTTONDOWN = 0x00A4; 130 public const int WM_NCRBUTTONUP = 0x00A5; 131 public const int WM_NCRBUTTONDBLCLK = 0x00A6; 132 public const int WM_NCMBUTTONDOWN = 0x00A7; 133 public const int WM_NCMBUTTONUP = 0x00A8; 134 public const int WM_NCMBUTTONDBLCLK = 0x00A9; 135 public const int WM_NCXBUTTONDOWN = 0x00AB; 136 public const int WM_NCXBUTTONUP = 0x00AC; 137 public const int WM_NCXBUTTONDBLCLK = 0x00AD; 138 public const int WM_INPUT_DEVICE_CHANGE = 0x00FE; 139 public const int WM_INPUT = 0x00FF; 140 public const int WM_KEYFIRST = 0x0100; 141 public const int WM_CHAR = 0x0102; 142 public const int WM_DEADCHAR = 0x0103; 143 public const int WM_SYSCHAR = 0x0106; 144 public const int WM_SYSDEADCHAR = 0x0107; 145 public const int WM_KEYLAST = 0x0109; 146 public const int WM_IME_STARTCOMPOSITION = 0x010D; 147 public const int WM_IME_ENDCOMPOSITION = 0x010E; 148 public const int WM_IME_COMPOSITION = 0x010F; 149 public const int WM_IME_KEYLAST = 0x010F; 150 public const int WM_INITDIALOG = 0x0110; 151 public const int WM_COMMAND = 0x0111; 152 public const int WM_SYSCOMMAND = 0x0112; 153 public const int WM_TIMER = 0x0113; 154 public const int WM_HSCROLL = 0x0114; 155 public const int WM_VSCROLL = 0x0115; 156 public const int WM_INITMENU = 0x0116; 157 public const int WM_INITMENUPOPUP = 0x0117; 158 public const int WM_GESTURE = 0x0119; 159 public const int WM_GESTURENOTIFY = 0x011A; 160 public const int WM_MENUSELECT = 0x011F; 161 public const int WM_MENUCHAR = 0x0120; 162 public const int WM_ENTERIDLE = 0x0121; 163 public const int WM_MENURBUTTONUP = 0x0122; 164 public const int WM_MENUDRAG = 0x0123; 165 public const int WM_MENUGETOBJECT = 0x0124; 166 public const int WM_UNINITMENUPOPUP = 0x0125; 167 public const int WM_MENUCOMMAND = 0x0126; 168 public const int WM_CHANGEUISTATE = 0x0127; 169 public const int WM_UPDATEUISTATE = 0x0128; 170 public const int WM_QUERYUISTATE = 0x0129; 171 public const int WM_CTLCOLORMSGBOX = 0x0132; 172 public const int WM_CTLCOLOREDIT = 0x0133; 173 public const int WM_CTLCOLORLISTBOX = 0x0134; 174 public const int WM_CTLCOLORBTN = 0x0135; 175 public const int WM_CTLCOLORDLG = 0x0136; 176 public const int WM_CTLCOLORSCROLLBAR = 0x0137; 177 public const int WM_CTLCOLORSTATIC = 0x0138; 178 public const int WM_MOUSEFIRST = 0x0200; 179 //public const int WM_LBUTTONDBLCLK = 0x0203; 180 //public const int WM_RBUTTONDBLCLK = 0x0206; 181 //public const int WM_MBUTTONDBLCLK = 0x0209; 182 public const int WM_MOUSEWHEEL = 0x020A; 183 public const int WM_XBUTTONDOWN = 0x020B; 184 public const int WM_XBUTTONUP = 0x020C; 185 public const int WM_XBUTTONDBLCLK = 0x020D; 186 public const int WM_MOUSEHWHEEL = 0x020E; 187 public const int WM_MOUSELAST = 0x020E; 188 public const int WM_PARENTNOTIFY = 0x0210; 189 public const int WM_ENTERMENULOOP = 0x0211; 190 public const int WM_EXITMENULOOP = 0x0212; 191 public const int WM_NEXTMENU = 0x0213; 192 public const int WM_SIZING = 0x0214; 193 public const int WM_CAPTURECHANGED = 0x0215; 194 public const int WM_MOVING = 0x0216; 195 public const int WM_POWERBROADCAST = 0x0218; 196 public const int WM_MDICREATE = 0x0220; 197 public const int WM_MDIDESTROY = 0x0221; 198 public const int WM_MDIACTIVATE = 0x0222; 199 public const int WM_MDIRESTORE = 0x0223; 200 public const int WM_MDINEXT = 0x0224; 201 public const int WM_MDIMAXIMIZE = 0x0225; 202 public const int WM_MDITILE = 0x0226; 203 public const int WM_MDICASCADE = 0x0227; 204 public const int WM_MDIICONARRANGE = 0x0228; 205 public const int WM_MDIGETACTIVE = 0x0229; 206 public const int WM_MDISETMENU = 0x0230; 207 public const int WM_ENTERSIZEMOVE = 0x0231; 208 public const int WM_EXITSIZEMOVE = 0x0232; 209 public const int WM_DROPFILES = 0x0233; 210 public const int WM_MDIREFRESHMENU = 0x0234; 211 public const int WM_POINTERDEVICECHANGE = 0x238; 212 public const int WM_POINTERDEVICEINRANGE = 0x239; 213 public const int WM_POINTERDEVICEOUTOFRANGE = 0x23A; 214 public const int WM_TOUCH = 0x0240; 215 public const int WM_NCPOINTERUPDATE = 0x0241; 216 public const int WM_NCPOINTERDOWN = 0x0242; 217 public const int WM_NCPOINTERUP = 0x0243; 218 public const int WM_POINTERUPDATE = 0x0245; 219 public const int WM_POINTERDOWN = 0x0246; 220 public const int WM_POINTERUP = 0x0247; 221 public const int WM_POINTERENTER = 0x0249; 222 public const int WM_POINTERLEAVE = 0x024A; 223 public const int WM_POINTERACTIVATE = 0x024B; 224 public const int WM_POINTERCAPTURECHANGED = 0x024C; 225 public const int WM_TOUCHHITTESTING = 0x024D; 226 public const int WM_POINTERWHEEL = 0x024E; 227 public const int WM_POINTERHWHEEL = 0x024F; 228 public const int WM_POINTERROUTEDTO = 0x0251; 229 public const int WM_POINTERROUTEDAWAY = 0x0252; 230 public const int WM_POINTERROUTEDRELEASED = 0x0253; 231 public const int WM_IME_SETCONTEXT = 0x0281; 232 public const int WM_IME_NOTIFY = 0x0282; 233 public const int WM_IME_CONTROL = 0x0283; 234 public const int WM_IME_COMPOSITIONFULL = 0x0284; 235 public const int WM_IME_SELECT = 0x0285; 236 public const int WM_IME_CHAR = 0x0286; 237 public const int WM_IME_REQUEST = 0x0288; 238 public const int WM_IME_KEYDOWN = 0x0290; 239 public const int WM_IME_KEYUP = 0x0291; 240 public const int WM_NCMOUSEHOVER = 0x02A0; 241 public const int WM_NCMOUSELEAVE = 0x02A2; 242 public const int WM_WTSSESSION_CHANGE = 0x02B1; 243 public const int WM_TABLET_FIRST = 0x02; 244 public const int WM_TABLET_LAST = 0x02; 245 public const int WM_DPICHANGED = 0x02E0; 246 public const int WM_DPICHANGED_BEFOREPARENT = 0x02E2; 247 public const int WM_DPICHANGED_AFTERPARENT = 0x02E3; 248 public const int WM_GETDPISCALEDSIZE = 0x02E4; 249 public const int WM_CUT = 0x0300; 250 public const int WM_COPY = 0x0301; 251 public const int WM_PASTE = 0x0302; 252 public const int WM_CLEAR = 0x0303; 253 public const int WM_UNDO = 0x0304; 254 public const int WM_RENDERFORMAT = 0x0305; 255 public const int WM_RENDERALLFORMATS = 0x0306; 256 public const int WM_DESTROYCLIPBOARD = 0x0307; 257 public const int WM_DRAWCLIPBOARD = 0x0308; 258 public const int WM_PAINTCLIPBOARD = 0x0309; 259 public const int WM_VSCROLLCLIPBOARD = 0x030A; 260 public const int WM_SIZECLIPBOARD = 0x030B; 261 public const int WM_ASKCBFORMATNAME = 0x030C; 262 public const int WM_CHANGECBCHAIN = 0x030D; 263 public const int WM_HSCROLLCLIPBOARD = 0x030E; 264 public const int WM_QUERYNEWPALETTE = 0x030F; 265 public const int WM_PALETTEISCHANGING = 0x0310; 266 public const int WM_PALETTECHANGED = 0x0311; 267 public const int WM_HOTKEY = 0x0312; 268 public const int WM_PRINT = 0x0317; 269 public const int WM_APPCOMMAND = 0x0319; 270 public const int WM_THEMECHANGED = 0x031A; 271 public const int WM_CLIPBOARDUPDATE = 0x031D; 272 public const int WM_DWMCOMPOSITIONCHANGED = 0x031E; 273 public const int WM_DWMNCRENDERINGCHANGED = 0x031F; 274 public const int WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320; 275 public const int WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321; 276 public const int WM_DWMSENDICONICTHUMBNAIL = 0x0323; 277 public const int WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326; 278 public const int WM_GETTITLEBARINFOEX = 0x033F; 279 public const int WM_HANDHELDFIRST = 0x0358; 280 public const int WM_HANDHELDLAST = 0x035F; 281 public const int WM_AFXFIRST = 0x0360; 282 public const int WM_AFXLAST = 0x037F; 283 public const int WM_PENWINFIRST = 0x0380; 284 public const int WM_PENWINLAST = 0x038F; 285 public const int WM_APP = 0x8000; 286 public const int WM_USER = 0x0400; 287 public const int WM_CT_REPEAT_FIRST_FIELD = 0x10; 288 public const int WM_CT_BOTTOM_FIELD_FIRST = 0x20; 289 public const int WM_CT_TOP_FIELD_FIRST = 0x40; 290 public const int WM_CT_INTERLACED = 0x80; 291 public const int WM_MAX_VIDEO_STREAMS = 0x3; 292 public const int WM_MAX_STREAMS = 0x3; 293 294 public const int WM_KEYDOWN = 0x100; 295 public const int WM_KEYUP = 0x101; 296 public const int WM_SYSKEYDOWN = 0x104; 297 public const int WM_SYSKEYUP = 0x105; 298 299 public const int WM_MOUSEMOVE = 0x200; 300 public const int WM_LBUTTONDOWN = 0x201; 301 public const int WM_RBUTTONDOWN = 0x204; 302 public const int WM_MBUTTONDOWN = 0x207; 303 public const int WM_LBUTTONUP = 0x202; 304 public const int WM_RBUTTONUP = 0x205; 305 public const int WM_MBUTTONUP = 0x208; 306 public const int WM_LBUTTONDBLCLK = 0x203; 307 public const int WM_RBUTTONDBLCLK = 0x206; 308 public const int WM_MBUTTONDBLCLK = 0x209; 309 } 310 }
KeyboardHook
using System; using System.Runtime.InteropServices; namespace KMHook { public class KeyboardHook : IDisposable { [DllImport("user32.dll")] private static extern int SetWindowsHookExA(int idHook, KeyboardDelegateHandler lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll")] private static extern int CallNextHookEx(int idHook, int nCode, int wParam, KeyData lParam); [DllImport("user32.dll")] public static extern bool UnhookWindowsHookEx(int idHook); private int hookType = 0; private delegate int KeyboardDelegateHandler(int nCode, int wParam, KeyData lParam); public delegate bool KeyDelegate(KeyData keyData, int message); public delegate bool KeyUpUpDelegate(KeyData keyData); public delegate bool KeyDownDelegate(KeyData keyData); public event KeyDelegate keyEvent; public event KeyUpUpDelegate keyUpEvent; public event KeyUpUpDelegate keyDownEvent; public bool IsHooked { get { if (hookType != 0) { return true; } return false; } } /// <summary> /// vkCode 表示1到254间的虚拟键盘码 /// scanCode 表示硬件扫描码 /// </summary> [StructLayout(LayoutKind.Sequential)] public class KeyData { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } public void SetupHook() { hookType = SetWindowsHookExA(HookType.WH_KEYBOARD_LL, KMProc, IntPtr.Zero, 0); if (hookType == 0) { RemoveHook(); } } private void RemoveHook() { bool retKeyboard = UnhookWindowsHookEx(hookType); if (retKeyboard) { hookType = 0; } } private int KMProc(int nCode, int wParam, KeyData lParam) { if (!(nCode >= 0)) { return CallNextHookEx(hookType, nCode, wParam, lParam); } bool shouldBlock = false; if (keyEvent != null) { shouldBlock = keyEvent.Invoke(lParam, wParam); } if (wParam == Messages.WM_KEYDOWN || wParam == Messages.WM_SYSKEYDOWN) { if (keyDownEvent != null) { shouldBlock = keyDownEvent.Invoke(lParam); } } if (wParam == Messages.WM_KEYUP || wParam == Messages.WM_SYSKEYUP) { if (keyUpEvent != null) { shouldBlock = keyUpEvent.Invoke(lParam); } } if (!shouldBlock) { return CallNextHookEx(hookType, nCode, wParam, lParam); } return 1; } public void Dispose() { RemoveHook(); } } }
MouseHook
using System; using System.Runtime.InteropServices; namespace KMHook { public class MouseHook: IDisposable { [DllImport("user32.dll")] private static extern int SetWindowsHookExA(int idHook, MouseDelegateHandler lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll")] private static extern bool UnhookWindowsHookEx(int idHook); [DllImport("user32.dll")] private static extern int CallNextHookEx(int idHook, int nCode, int wParam, MouseData lParam); private delegate int MouseDelegateHandler(int nCode, int wParam, MouseData lParam); public delegate bool MouseDelegate(MouseData pt, int message); public event MouseDelegate mouseEvent; private int hookType = 0; [StructLayout(LayoutKind.Sequential)] public class Point { public int x; public int y; } [StructLayout(LayoutKind.Sequential)] public class MouseData { public Point pt; public int hWnd; public int wHitTestCode; public int dwExtraInfo; } public bool IsHooked { get { if (hookType != 0) { return true; } return false; } } public void SetupHook() { hookType = SetWindowsHookExA(HookType.WH_MOUSE_LL, KMProc, IntPtr.Zero, 0); if (hookType == 0) { RemoveHook(); } } private void RemoveHook() { bool retKeyboard = UnhookWindowsHookEx(hookType); if (retKeyboard) { hookType = 0; } } private int KMProc(int nCode, int wParam, MouseData lParam) { if (!(nCode >= 0)) { return CallNextHookEx(hookType, nCode, wParam, lParam); } bool shouldBlock = false; if (mouseEvent != null) { shouldBlock = mouseEvent.Invoke(lParam, wParam); } if (!shouldBlock) { return CallNextHookEx(hookType, nCode, wParam, lParam); } return 1; } public void Dispose() { RemoveHook(); } } }
代码使用情况
KeyboardHook keyboardHook = new KeyboardHook(); keyboardHook.keyEvent += (keyData, message) => { if (message == Messages.WM_KEYDOWN || message == Messages.WM_SYSKEYDOWN) { if (keyData.vkCode == (int) Keys.A) Console.WriteLine("key a pressed."); if (keyData.vkCode == (int) Keys.F1) Console.WriteLine("f1 pressed."); if (keyData.vkCode == (int) Keys.Delete) Console.WriteLine("delete pressed."); if (keyData.vkCode == (int) Keys.LControlKey) Console.WriteLine("left control pressed."); } return true; }; keyboardHook.SetupHook();