定義資料結構
/// <summary> /// 宣告鍵盤鉤子的封送結構型別 /// </summary> [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode;//表示一個1到254間的虛擬鍵盤碼 public int scanCode;//表示硬體掃描碼 public int flags; public int time; public int dwExtraInfo; }
宣告Hook相關方法
//使用WINDOWS API函式代替獲取當前實體的函式,防止鉤子失效 [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string lpModuleName); //安裝鉤子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); //下一個鉤子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); //卸載鉤子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(int idHook); // 取得當前執行緒編號(執行緒鉤子需要用到) [DllImport("kernel32.dll")] static extern int GetCurrentThreadId();
Hook攔截方法
全域Hook
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null)) { KeyboardHookStruct MyKBHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); //引發OnKeyDownEvent if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { Keys keyData = (Keys)MyKBHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); OnKeyDownEvent(this, e); } } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); }
執行緒Hook
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null)) { //引發OnKeyDownEvent if (OnKeyDownEvent != null && nCode==0) { Keys keyData = (Keys)wParam; KeyEventArgs e = new KeyEventArgs(keyData); OnKeyDownEvent(this, e); } } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); }
全域/執行緒Hook引數結構區別
執行緒Hook KeyboardHookProc函式的各個引數意義如下:
nCode 訊息的型別,分HC_ACTION和HC_NOREMOVE
wParam 按鍵的虛擬鍵碼
lParam 按鍵的相關引數資訊,包括重復時間、按鍵的狀態(按下或彈起)等
全域Hook KeyboardHookProc函式的各個引數意義如下:
nCode 訊息的型別,有HC_ACTION
wParam 按鍵的狀態(按下或彈起)WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP
lParam 指向KeyboardHookStruct結構的指標,該結構包含了按鍵的詳細資訊,
添加Hook
全域Hook
public void Start() { if (hKeyboardHook == 0) { KeyboardHookProcedure = new HookProc(KeyboardHookProc); using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess()) using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule) hKeyboardHook = SetWindowsHookEx(13, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0); if (hKeyboardHook == 0) { Stop(); throw new Exception("Set GlobalKeyboardHook failed!"); } } }
執行緒Hook
public void Start() { if (hKeyboardHook == 0) { KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx(2, KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId()); if (hKeyboardHook == 0) { Stop(); throw new Exception("Set GlobalKeyboardHook failed!"); } } }
注:idHook 鉤子型別,即確定鉤子監聽何種訊息
執行緒鉤子監聽鍵盤訊息應設為2,全域鉤子監聽鍵盤訊息應設為13
執行緒鉤子監聽滑鼠訊息應設為7,全域鉤子監聽滑鼠訊息應設為14
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/270462.html
標籤:WinForm
上一篇:C# 自定義時間進度條
下一篇:WPF 筆跡觸摸點收集工具
