[Winform]通过钩子监控键盘操作和鼠标移动
摘要
有这样一个需求,在程序隐藏之后,需要监控当前电脑是否有操作,如果1分钟内,无操作,则弹出视频,循环播放。
解决办法
从网上找的一个解决办法,可以通过钩子的方式实现,这里记录一下。
/// <summary> ///监控键盘钩子 /// </summary> public class KeyboardHook { private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; private const int WM_SYSKEYDOWN = 0x104; private const int WM_SYSKEYUP = 0x105; //全局事件 public event KeyEventHandler OnKeyDownEvent; public event KeyEventHandler OnKeyUpEvent; public event KeyPressEventHandler OnKeyPressEvent; static int hKeyboardHook = 0; //鼠标常量 public const int WH_KEYBOARD_LL = 13; public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); //声明键盘钩子事件类型 HookProc KeyboardHookProcedure; /// <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; } [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); 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); } 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(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0); if (hKeyboardHook == 0) { Stop(); throw new Exception("Set GlobalKeyboardHook failed!"); } } } public void Stop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (!retKeyboard) throw new Exception("Unload GlobalKeyboardHook failed!"); } //构造函数中安装钩子 public KeyboardHook() { } //析构函数中卸载钩子 ~KeyboardHook() { Stop(); } }
/// <summary> /// 监控鼠标钩子 /// </summary> public class MouseHook { private const int WM_MOUSEMOVE = 0x200; private const int WM_LBUTTONDOWN = 0x201; private const int WM_RBUTTONDOWN = 0x204; private const int WM_MBUTTONDOWN = 0x207; private const int WM_LBUTTONUP = 0x202; private const int WM_RBUTTONUP = 0x205; private const int WM_MBUTTONUP = 0x208; private const int WM_LBUTTONDBLCLK = 0x203; private const int WM_RBUTTONDBLCLK = 0x206; private const int WM_MBUTTONDBLCLK = 0x209; //全局的事件 public event MouseEventHandler OnMouseActivity; static int hMouseHook = 0; //鼠标钩子句柄 //鼠标常量 public const int WH_MOUSE_LL = 14; //mouse hook constant HookProc MouseHookProcedure; //声明鼠标钩子事件类型. //声明一个Point的封送类型 [StructLayout(LayoutKind.Sequential)] public class POINT { public int x; public int y; } //声明鼠标钩子的封送结构类型 [StructLayout(LayoutKind.Sequential)] public class MouseHookStruct { public POINT pt; public int hWnd; public int wHitTestCode; public int dwExtraInfo; } [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 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); public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); /// <summary> /// 墨认的构造函数构造当前类的实例. /// </summary> public MouseHook() { } //析构函数. ~MouseHook() { Stop(); } public void Start() { //安装鼠标钩子 if (hMouseHook == 0) { //生成一个HookProc的实例. MouseHookProcedure = new HookProc(MouseHookProc); using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess()) using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule) hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, GetModuleHandle(curModule.ModuleName), 0); //如果装置失败停止钩子 if (hMouseHook == 0) { Stop(); throw new Exception("SetWindowsHookEx failed."); } } } public void Stop() { bool retMouse = true; if (hMouseHook != 0) { retMouse = UnhookWindowsHookEx(hMouseHook); hMouseHook = 0; } //如果卸下钩子失败 if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed."); } private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) { //如果正常运行并且用户要监听鼠标的消息 if ((nCode >= 0) && (OnMouseActivity != null)) { MouseButtons button = MouseButtons.None; int clickCount = 0; switch (wParam) { case WM_LBUTTONDOWN: button = MouseButtons.Left; clickCount = 1; break; case WM_LBUTTONUP: button = MouseButtons.Left; clickCount = 1; break; case WM_LBUTTONDBLCLK: button = MouseButtons.Left; clickCount = 2; break; case WM_RBUTTONDOWN: button = MouseButtons.Right; clickCount = 1; break; case WM_RBUTTONUP: button = MouseButtons.Right; clickCount = 1; break; case WM_RBUTTONDBLCLK: button = MouseButtons.Right; clickCount = 2; break; } //从回调函数中得到鼠标的信息 MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0); OnMouseActivity(this, e); } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } }
使用
public partial class Form1 : Form { public Form1() { InitializeComponent(); } KeyboardHook key = new KeyboardHook(); MouseHook mouse = new MouseHook(); private void Form1_Load(object sender, EventArgs e) { mouse.OnMouseActivity += mouse_OnMouseActivity; key.OnKeyDownEvent += key_OnKeyDownEvent; mouse.Start(); key.Start(); this.FormClosing += Form1_FormClosing; } void Form1_FormClosing(object sender, FormClosingEventArgs e) { key.Stop(); mouse.Stop(); } void key_OnKeyDownEvent(object sender, System.Windows.Forms.KeyEventArgs e) { this.Text = e.KeyData.ToString(); } void mouse_OnMouseActivity(object sender, System.Windows.Forms.MouseEventArgs e) { this.Text = "X=" + e.X + ",Y=" + e.Y; } }
测试
最小化到任务栏之后
原文
-
博客地址:http://www.cnblogs.com/wolf-sun/
博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2014-07-27 [C#基础]Func和Action学习