123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using System.Text;
- namespace Veldrid.Common
- {
- class KeyboardHook
- {
- #region 常数和结构
- #region wParam对应的按钮事件
- public const int WM_KEYDOWN = 0x100; // 键盘被按下
- public const int WM_KEYUP = 0x101; // 键盘被松开
- public const int WM_SYSKEYDOWN = 0x104; // 键盘被按下,这个是系统键被按下,例如Alt、Ctrl等键
- public const int WM_SYSKEYUP = 0x105; // 键盘被松开,这个是系统键被松开,例如Alt、Ctrl等键
- #endregion
- public const int WH_KEYBOARD_LL = 13;
- [StructLayout(LayoutKind.Sequential)] //声明键盘钩子的封送结构类型
- public class KeyboardHookStruct
- {
- public int vkCode; //表示一个在1到254间的虚似键盘码
- public int scanCode; //表示硬件扫描码
- public int flags;
- public int time;
- public int dwExtraInfo;
- }
- #endregion
- #region 成员变量、委托、事件
- private static int hHook;
- private static HookProc KeyboardHookDelegate;
- // 键盘回调委托
- public delegate void KeyboardHandler(Int32 wParam, KeyboardHookStruct keyboardHookStruct);
- // 键盘回调事件
- private static event KeyboardHandler Handlers;
- // 锁
- private readonly object lockObject = new object();
- // 当前状态,是否已经启动
- private volatile bool isStart = false;
- #endregion
- #region Win32的Api
- [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
- private static extern int GetWindowThreadProcessId(System.IntPtr hWnd, IntPtr intPtr);
- private delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
- //安装钩子的函数
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]
- private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
- //卸下钩子的函数
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =CallingConvention.StdCall)]
- private static extern bool UnhookWindowsHookEx(int idHook);
- //下一个钩挂的函数
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam,IntPtr lParam);
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- private static extern IntPtr GetModuleHandle(string lpModuleName);
- #endregion
- #region 单例模式
- private static volatile KeyboardHook MyKeyboard;
- private readonly static object createLock = new object();
- private KeyboardHook() { }
- public static KeyboardHook GetKeyboardHook()
- {
- if (MyKeyboard == null)
- {
- lock (createLock)
- {
- if (MyKeyboard == null)
- {
- MyKeyboard = new KeyboardHook();
- }
- }
- }
- return MyKeyboard;
- }
- #endregion
- /// <summary>
- /// 安装钩子
- /// </summary>
- public void Start(IntPtr hwnd)
- {
- if (isStart)
- {
- return;
- }
- lock (lockObject)
- {
- if (isStart)
- {
- return;
- }
- if (Handlers == null)
- {
- throw new Exception("Please set handler first!Then run Start");
- }
- KeyboardHookDelegate = new HookProc(KeyboardHookProc);
- var handle = GetWindowThreadProcessId(hwnd, IntPtr.Zero);
- hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, IntPtr.Zero, handle);
- isStart = true;
- }
- }
- /// <summary>
- /// 卸载钩子
- /// </summary>
- public void Stop()
- {
- if (!isStart)
- {
- return;
- }
- lock (lockObject)
- {
- if (!isStart)
- {
- return;
- }
- UnhookWindowsHookEx(hHook);
- // 清除所有事件
- Handlers = null;
- isStart = false;
- }
- }
- /// <summary>
- /// 键盘的系统回调函数
- /// </summary>
- /// <param name="nCode"></param>
- /// <param name="wParam"></param>
- /// <param name="lParam"></param>
- /// <returns></returns>
- private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
- {
- //如果该消息被丢弃(nCode<0)或者没有事件绑定处理程序则不会触发事件
- if ((nCode >= 0) && Handlers != null)
- {
- KeyboardHookStruct KeyDataFromHook =(KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
- Handlers(wParam, KeyDataFromHook);
- }
- return CallNextHookEx(hHook, nCode, wParam, lParam);
- }
- /// <summary>
- /// 添加按键的回调函数
- /// </summary>
- /// <param name="handler"></param>
- public void AddKeyboardHandler(KeyboardHandler handler)
- {
- Handlers += handler;
- }
- /// <summary>
- /// 删除指定按键的回调函数
- /// </summary>
- /// <param name="handler"></param>
- public void RemoveKeyboardHandler(KeyboardHandler handler)
- {
- if (Handlers != null)
- {
- Handlers -= handler;
- }
- }
- }
- class MouseHook
- {
- #region 常量
- 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 WH_MOUSE_LL = 14; //可以截获整个系统所有模块的鼠标事件。
- #endregion
- #region 成员变量、回调函数、事件
- /// <summary>
- /// 钩子回调函数
- /// </summary>
- /// <param name="nCode">如果代码小于零,则挂钩过程必须将消息传递给CallNextHookEx函数,而无需进一步处理,并且应返回CallNextHookEx返回的值。此参数可以是下列值之一。(来自官网手册)</param>
- /// <param name="wParam">记录了按下的按钮</param>
- /// <param name="lParam"></param>
- /// <returns></returns>
- public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
- /// <summary>
- /// 全局的鼠标事件
- /// </summary>
- /// <param name="wParam"> 代表发生的鼠标的事件 </param>
- /// <param name="mouseMsg">钩子的结构体,存储着鼠标的位置及其他信息</param>
- public delegate void MyMouseEventHandler(Int32 wParam, MouseHookStruct mouseMsg);
- private event MyMouseEventHandler OnMouseActivity;
- // 声明鼠标钩子事件类型
- private HookProc _mouseHookProcedure;
- private static int _hMouseHook = 0; // 鼠标钩子句柄
- // 锁
- private readonly object lockObject = new object();
- // 当前状态,是否已经启动
- private bool isStart = false;
- #endregion
- #region Win32的API
- /// <summary>
- /// 钩子结构体
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- public class MouseHookStruct
- {
- public POINT pt; // 鼠标位置
- public int hWnd;
- public int wHitTestCode;
- public int dwExtraInfo;
- }
- //声明一个Point的封送类型
- [StructLayout(LayoutKind.Sequential)]
- public class POINT
- {
- public int x;
- public int y;
- }
- // 装置钩子的函数
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
- // 卸下钩子的函数
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- private static extern bool UnhookWindowsHookEx(int idHook);
- [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
- private static extern int GetWindowThreadProcessId(System.IntPtr hWnd, IntPtr intPtr);
- // 下一个钩挂的函数
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
- #endregion
- #region 构造(单例模式)与析构函数
- private static volatile MouseHook MyMouseHook;
- private readonly static object createLock = new object();
- private MouseHook() { }
- public static MouseHook GetMouseHook()
- {
- if (MyMouseHook == null)
- {
- lock (createLock)
- {
- if (MyMouseHook == null)
- {
- MyMouseHook = new MouseHook();
- }
- }
- }
- return MyMouseHook;
- }
- /// <summary>
- /// 析构函数
- /// </summary>
- ~MouseHook()
- {
- Stop();
- }
- #endregion
- /// <summary>
- /// 启动全局钩子
- /// </summary>
- public void Start(IntPtr intPtr)
- {
- if (isStart)
- {
- return;
- }
- lock (lockObject)
- {
- if (isStart)
- {
- return;
- }
- if (OnMouseActivity == null)
- {
- throw new Exception("Please set handler first!Then run Start");
- }
- // 安装鼠标钩子
- if (_hMouseHook == 0)
- {
- var handle = GetWindowThreadProcessId(intPtr, IntPtr.Zero);
- // 生成一个HookProc的实例.
- _mouseHookProcedure = new HookProc(MouseHookProc);
- _hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, _mouseHookProcedure, IntPtr.Zero, handle);
- //假设装置失败停止钩子
- if (_hMouseHook == 0)
- {
- Stop();
- throw new Exception("SetWindowsHookEx failed.");
- }
- }
- isStart = true;
- }
- }
- /// <summary>
- /// 停止全局钩子
- /// </summary>
- public void Stop()
- {
- if (!isStart)
- {
- return;
- }
- lock (lockObject)
- {
- if (!isStart)
- {
- return;
- }
- bool retMouse = true;
- if (_hMouseHook != 0)
- {
- retMouse = UnhookWindowsHookEx(_hMouseHook);
- _hMouseHook = 0;
- }
- // 假设卸下钩子失败
- if (!(retMouse))
- throw new Exception("UnhookWindowsHookEx failed.");
- // 删除所有事件
- OnMouseActivity = null;
- // 标志位改变
- isStart = false;
- }
- }
- /// <summary>
- /// 鼠标钩子回调函数
- /// </summary>
- private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
- {
- // 假设正常执行而且用户要监听鼠标的消息
- if ((nCode >= 0) && (OnMouseActivity != null))
- {
- MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
- OnMouseActivity(wParam, MyMouseHookStruct);
- }
- // 启动下一次钩子
- return CallNextHookEx(_hMouseHook, nCode, wParam, lParam);
- }
- /// <summary>
- /// 注册全局鼠标事件
- /// </summary>
- /// <param name="handler"></param>
- public void AddMouseHandler(MyMouseEventHandler handler)
- {
- OnMouseActivity += handler;
- }
- /// <summary>
- /// 注销全局鼠标事件
- /// </summary>
- /// <param name="handler"></param>
- public void RemoveMouseHandler(MyMouseEventHandler handler)
- {
- if (OnMouseActivity != null)
- {
- OnMouseActivity -= handler;
- }
- }
- }
- }
|