千家信息网

winform键盘全局与线程Hook的使用方法

发表于:2024-10-05 作者:千家信息网编辑
千家信息网最后更新 2024年10月05日,这篇文章主要讲解了"winform键盘全局与线程Hook的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"winform键盘全局与线程Hook的
千家信息网最后更新 2024年10月05日winform键盘全局与线程Hook的使用方法

这篇文章主要讲解了"winform键盘全局与线程Hook的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"winform键盘全局与线程Hook的使用方法"吧!

定义数据结构

/// /// 声明键盘钩子的封送结构类型///         [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)); //引发OnKeyDownEventif (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))            {               //引发OnKeyDownEventif (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_NOREMOVEwParam    按键的虚拟键码 lParam    按键的相关参数信息,包括重复时间、按键的状态(按下或弹起)等全局Hook KeyboardHookProc函数的各个参数意义如下:nCode    消息的类型,有HC_ACTIONwParam    按键的状态(按下或弹起)WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUPlParam    指向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

感谢各位的阅读,以上就是"winform键盘全局与线程Hook的使用方法"的内容了,经过本文的学习后,相信大家对winform键盘全局与线程Hook的使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0