键盘钩子,钩子(二)

上一篇实现了键盘的KeyDown,继续实现鼠标的MouseDown事件,还记得上篇SetWindowsHookEx函数第一个参数说明么? 第一个参数,如果是全局钩子监听键盘消息应设为13,全局钩子监听鼠标消息设为14。是不是很简单,直接看代码吧: 钩子类(Hook.cs):
namespace Win32Hook { public class Hook { #region Windows 消息 private const int WM_SYSKEYDOWN = 0x104; // 键盘按下 private const int WM_KEYDOWN = 0x100; // 鼠标左键 private const int WM_LBUTTONDOWN = 0x201; // 鼠标右键 private const int WM_RBUTTONDOWN = 0x204; // 鼠标滑轮 private const int WM_MOUSEWHEEL = 0x020A; // 鼠标左键双击 private const int WM_LBUTTONDBLCLK = 0x203; // 鼠标右键双击 private const int WM_RBUTTONDBLCLK = 0x206; #endregion #region API //安装钩子 [DllImport("user32.dll")] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); //卸载钩子 [DllImport("user32.dll")] public static extern bool UnhookWindowsHookEx(int idHook); //调用下一个钩子 [DllImport("user32.dll")] public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); //获取动态链接库句柄 [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name); #endregion #region int hKeyboardHook = 0; int hMouseHook = 0; // 全局键盘钩子 private const int WH_KEYBOARD_LL = 13; // 全局鼠标钩子 private const int WH_MOUSE_LL = 14; // 定义钩子委托 public delegate int HookProc(int nCode, int wParam, IntPtr lParam); // 键盘钩子 HookProc KeyBoardHookProcedure; // 鼠标钩子 HookProc MouseHookProcedure; //键盘KeyDown事件 public event KeyEventHandler KeyDown; //鼠标MouseDown事件 public event MouseEventHandler MouseDown; #region 键盘Hook结构函数 [StructLayout(LayoutKind.Sequential)] public class KeyBoardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } #endregion #region 鼠标Hook结构函数 [StructLayout(LayoutKind.Sequential)] private class POINT { public int x; public int y; } [StructLayout(LayoutKind.Sequential)] private class MouseLLHookStruct { public POINT pt; public int mouseData; public int flags; public int time; public int dwExtraInfo; } #endregion #endregion #region 安装钩子 /// /// 安装钩子 /// /// 是否安装成功 public bool Start() { return Start(true, true); } /// /// 安装钩子 /// /// 安装鼠标钩子,true安装,false不安装
/// 安装键盘钩子,true安装,false不安装
/// 是否安装成功 public bool Start(bool InstallMouseHook, bool InstallKeyboardHook) { #region 安装键盘钩子 if (InstallKeyboardHook) { KeyBoardHookProcedure = new HookProc(KeyBoardHookProc); // 返回值int 如果返回0,则安装失败 hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); // 如果键盘钩子安装失败 if (hKeyboardHook == 0) Stop(false, true); } #endregion #region 安装鼠标钩子 if (InstallMouseHook) { MouseHookProcedure = new HookProc(MouseHookProc); // 返回值int 如果返回0,则安装失败 hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); // 如果鼠标钩子安装失败 if (hMouseHook == 0) Stop(true, false); } #endregion if (InstallKeyboardHook && InstallMouseHook) return hKeyboardHook != 0 && hMouseHook != 0; else if (InstallKeyboardHook) return hKeyboardHook != 0; else if (InstallMouseHook) return hMouseHook != 0; else return false; } #endregion #region 卸载钩子 /// /// 卸载钩子 /// /// 是否卸载成功 public bool Stop() { return this.Stop(true, true); } /// /// 卸载钩子 /// /// 卸载鼠标钩子,true卸载,false不卸载
/// 卸载键盘钩子,true卸载,false不卸载
/// 是否卸载成功 public bool Stop(bool UninstallMouseHook, bool UninstallKeyboardHook) { bool retKeyboard = true; bool retMouse = true; // 卸载键盘钩子 if (hKeyboardHook != 0 && UninstallKeyboardHook) { // 返回为bool true为卸载成功,false卸载失败 retKeyboard = UnhookWindowsHookEx(hKeyboardHook); } // 卸载鼠标钩子 if (hMouseHook != 0 && UninstallMouseHook) { // 返回为bool true为卸载成功,false卸载失败 retMouse = UnhookWindowsHookEx(hMouseHook); } return retKeyboard && retMouse; } #endregion #region 钩子消息处理 //键盘钩子消息处理方法,此处可以做很多事,比如说,屏蔽快捷键,添加键盘事件 public int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam) { bool handled = false; if (nCode >= 0 && KeyDown != null) { KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct)); // KeyDown事件,不单单可以加KeyDown事件,也可以加KeyUp等等 if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { Keys keyData = (Keys)kbh.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); KeyDown(this, e); handled = handled || e.Handled; } } if (handled) return 1; else // 继续消息循环 return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } //鼠标钩子消息处理方法,自己DIY吧 private int MouseHookProc(int nCode, int wParam, IntPtr lParam) { if ((nCode >= 0) && (MouseDown != null)) { MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct)); MouseButtons button = MouseButtons.None; short mouseDelta = 0; // 判断鼠标按键 switch (wParam) { case WM_LBUTTONDOWN: button = MouseButtons.Left; break; case WM_RBUTTONDOWN: button = MouseButtons.Right; break; case WM_MOUSEWHEEL: mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff); break; } int clickCount = 0; if (button != MouseButtons.None) { if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2; else clickCount = 1; MouseEventArgs e = new MouseEventArgs(button, clickCount, mouseHookStruct.pt.x, mouseHookStruct.pt.y, mouseDelta); MouseDown(this, e); } } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } #endregion } }

窗体类(Form1.cs):
public partial class Form1 : Form { Hook hook; public Form1() { InitializeComponent(); hook = new Hook(); hook.KeyDown += new KeyEventHandler(hook_KeyDown); hook.MouseDown += new MouseEventHandler(hook_MouseDown); hook.Start(); } void hook_MouseDown(object sender, MouseEventArgs e) { SetMessage("MouseDown:X:" + e.X + " Y:" + e.Y + " button:" + e.Button); } void hook_KeyDown(object sender, KeyEventArgs e) { SetMessage("KeyDown:" + e.KeyCode); } private void SetMessage(string message) { textBox1.AppendText(message + "\r\n"); textBox1.ScrollToCaret(); } }
运行程序,此时,按下的键盘键值和鼠标坐标按键都会记录在程序中 效果图:
键盘钩子,钩子(二)
事例下载
Tags:  钩子函数 加载全局钩子 钩子注入 悬钩子 键盘钩子

延伸阅读

最新评论

发表评论