using PTMedicalInsurance.Variables; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace PTMedicalInsurance.Common.Hook { public class HookManager { #region 钩子类型的枚举 public const int WH_JOURNALRECORD = 0; //监视和记录输入事件。安装一个挂钩处理过程,对寄送至系统消息队列的输入消息进行纪录 public const int WH_JOURNALPLAYBACK = 1; //回放用WH_JOURNALRECORD记录事件 public const int WH_KEYBOARD = 2; //键盘钩子,键盘触发消息。WM_KEYUP或WM_KEYDOWN消息 public const int WH_GETMESSAGE = 3; //发送到窗口的消息。GetMessage或PeekMessage触发 public const int WH_CALLWNDPROC = 4; //发送到窗口的消息。由SendMessage触发 public const int WH_CBT = 5; //当基于计算机的训练(CBT)事件发生时 public const int WH_SYSMSGFILTER = 6; //同WH_MSGFILTER一样,系统范围的。 public const int WH_MOUSE = 7; //鼠标钩子,查询鼠标事件消息 public const int WH_HARDWARE = 8; //非鼠标、键盘消息时 public const int WH_DEBUG = 9; //调试钩子,用来给钩子函数除错 public const int WH_SHELL = 10; //外壳钩子,当关于WINDOWS外壳事件发生时触发. public const int WH_FOREGROUNDIDLE = 11; //前台应用程序线程变成空闲时候,钩子激活。 public const int WH_CALLWNDPROCRET = 12; //发送到窗口的消息。由SendMessage处理完成返回时触发 public const int WH_KEYBOARD_LL = 13; //此挂钩只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视 public const int WH_MOUSE_LL = 14; //此挂钩只能在Windows NT中被安装,用来对底层的鼠标输入事件进行监视 public const int WM_MOUSEMOVE = 0x200; public const int WM_LBUTTONDOWN = 0x201; public const int WM_RBUTTONDOWN = 0x204; public const int WM_MBUTTONDOWN = 0x207; public const int WM_LBUTTONUP = 0x202; public const int WM_RBUTTONUP = 0x205; public const int WM_MBUTTONUP = 0x208; public const int WM_LBUTTONDBLCLK = 0x203; public const int WM_RBUTTONDBLCLK = 0x206; public const int WM_MBUTTONDBLCLK = 0x209; public const int WM_KEYDOWN = 256; #endregion public delegate int HookProc(int nCode, int wParam, IntPtr lParam); // 安装钩子 [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 bool UnhookWindowsHookEx(int idHook); // 继续下一个钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); // 取得当前线程编号 [DllImport("kernel32.dll")] static extern int GetCurrentThreadId(); [DllImport("kernel32.dll", SetLastError = true)] private static extern uint GetLastError(); [DllImport("kernel32.dll")] static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr GetModuleHandle(string lpModuleName); static int hMouseHook = 0; HookProc MouseHookProcedure; static int hKeyboardHook = 0; HookProc KeyboardHookProcedure; static int hWindowHook = 0; HookProc WindowHookProcedure; private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { if (nCode >= 0 && wParam == WM_KEYDOWN) { int vkCode = Marshal.ReadInt32(lParam); //按键ascii码 if (vkCode.ToString() == "13") { MessageBox.Show("按了Enter"); } //返回1 相当于屏蔽了Enter return 1; } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) { if (nCode >= 0) { switch (wParam) { case WM_LBUTTONDOWN: MessageBox.Show("鼠标左键按下"); break; case WM_LBUTTONUP: MessageBox.Show("鼠标左键抬起"); break; case WM_LBUTTONDBLCLK: MessageBox.Show("鼠标左键双击"); break; case WM_RBUTTONDOWN: MessageBox.Show("鼠标右键按下"); break; case WM_RBUTTONUP: MessageBox.Show("鼠标右键抬起"); break; case WM_RBUTTONDBLCLK: MessageBox.Show("鼠标右键双击"); break; } } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } private int WindowHookProc(int nCode, Int32 wParam, IntPtr lParam) { if (nCode >= 0) { switch (wParam) { case WH_CALLWNDPROC: Global.writeLog("窗体消息过程"); break; case WH_CBT: Global.writeLog("窗体创建"); break; default: Global.writeLog("窗体创建1"); //Logger.writeLog($"{wParam}"); break; } } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } // 安装钩子 public void HookStart(IntPtr hInstance,int threadId) { //hInstance = LoadLibrary("User32"); if (hWindowHook == 0) { // 创建HookProc实例 WindowHookProcedure = new HookProc(WindowHookProc); // 设置钩子 hWindowHook = SetWindowsHookEx(WH_CBT, WindowHookProcedure, hInstance, threadId); // 如果设置钩子失败 if (hWindowHook == 0) { uint lastError = GetLastError(); HookStop(); MessageBox.Show($"SetWindowsHookEx failed.Error code: {lastError}"); //throw new Exception($"SetWindowsHookEx failed.Error code: {lastError}"); } } //if (hKeyboardHook == 0) //{ // // 创建HookProc实例 // KeyboardHookProcedure = new HookProc(KeyboardHookProc); // // 设置钩子 // hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, hInstance, 0); // // 如果设置钩子失败 // if (hKeyboardHook == 0) // { // HookStop(); // throw new Exception("SetWindowsHookEx failed."); // } //} //if (hMouseHook == 0) //{ // MouseHookProcedure = new HookProc(MouseHookProc); // hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, hInstance, 0); // // 如果设置钩子失败 // if (hMouseHook == 0) // { // HookStop(); // throw new Exception("SetWindowsHookEx failed."); // } //} } // 卸载钩子 public void HookStop() { bool retKeyboard = true; bool retMouse = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (hMouseHook != 0) { retMouse = UnhookWindowsHookEx(hMouseHook); hMouseHook = 0; } if (hWindowHook != 0) { retMouse = UnhookWindowsHookEx(hWindowHook); hWindowHook = 0; } if (!(retMouse && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed."); } } }