winform使用钩子限制windows热键
Posted teng-0802
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winform使用钩子限制windows热键相关的知识,希望对你有一定的参考价值。
新增类KeybordHookProc
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace HookDemo { /// <summary> /// 这个类可以让你得到一个在运行中程序的所有键盘事件 /// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息 /// </summary> public class KeyBordHook { private const byte LLKHF_ALTDOWN = 0x20; private const byte VK_CAPITAL = 0x14; private const byte VK_ESCAPE = 0x1B; private const byte VK_F4 = 0x73; private const byte VK_LCONTROL = 0xA2; private const byte VK_NUMLOCK = 0x90; private const byte VK_RCONTROL = 0xA3; private const byte VK_SHIFT = 0x10; private const byte VK_TAB = 0x09; public const int WH_KEYBOARD = 13; private const int WH_MOUSE = 7; private const int WH_MOUSE_LL = 14; private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; private const int WM_LBUTTONDBLCLK = 0x203; private const int WM_LBUTTONDOWN = 0x201; private const int WM_LBUTTONUP = 0x202; private const int WM_MBUTTONDBLCLK = 0x209; private const int WM_MBUTTONDOWN = 0x207; private const int WM_MBUTTONUP = 0x208; private const int WM_MOUSEMOVE = 0x200; private const int WM_MOUSEWHEEL = 0x020A; private const int WM_RBUTTONDBLCLK = 0x206; private const int WM_RBUTTONDOWN = 0x204; private const int WM_RBUTTONUP = 0x205; 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; //keyboard hook constant HookProc KeyboardHookProcedure; //声明键盘钩子事件类型. //声明键盘钩子的封送结构类型 [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode; //表示一个在1到254间的虚似键盘码 public int scanCode; //表示硬件扫描码 public int flags; public int time; public int dwExtraInfo; } //装置钩子的函数 [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")] private static extern int GetCurrentThreadId(); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern short GetKeyState(int vKey); public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); /// <summary> /// 墨认的构造函数构造当前类的实例并自动的运行起来. /// </summary> public KeyBordHook() { Start(); } //析构函数. ~KeyBordHook() { Stop(); } /// <summary> /// 启动Hook,并用流屏蔽任务管理器 /// </summary> public void Start() { if (hKeyboardHook == 0) { // 创建HookProc实例 KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0); // 如果设置钩子失败 if (hKeyboardHook == 0) { Stop(); AppLog.Error("SetWindowsHookEx failed."); } ////用二进制流的方法打开任务管理器。而且不关闭流.这样任务管理器就打开不了 //MyFs = new FileStream(Environment.ExpandEnvironmentVariables("%windir%\system32\taskmgr.exe"), // FileMode.Open); //byte[] MyByte = new byte[(int)MyFs.Length]; //MyFs.Write(MyByte, 0, (int)MyFs.Length); } } /// <summary> /// 卸载Hook /// </summary> public void Stop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } //if (null != MyFs) //{ // MyFs.Close(); //} if (!(retKeyboard)) { AppLog.Error("UnhookWindowsHookEx failed."); } } #region Nested type: KeyMSG public struct KeyMSG { public int dwExtraInfo; public int flags; public int scanCode; public int time; public int vkCode; } #endregion /// <summary> /// 键盘钩子 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { KeyboardHookStruct m = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); AppLog.Debug($"nCode is :{nCode} -- vkCode is :{m.vkCode}"); if (m.vkCode == (int)Keys.LWin || m.vkCode == (int)Keys.RWin || m.vkCode == (int)Keys.LWin && m.vkCode == (int)Keys.D || m.vkCode == (int)Keys.RWin && m.vkCode == (int)Keys.D || m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control || m.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt || m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt || m.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt || m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift || (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete ) { AppLog.Info("hooc is OK"); return 1; } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } } }
添加键盘按键触发事件
/// <summary> /// 键盘按下触发事件 /// </summary> void kh_OnKeyDownEvent(object sender, KeyEventArgs e) { }
键盘钩子的使用
/// <summary>
/// 键盘钩子
/// </summary>
KeyBordHook _keyBordHook;
//键盘钩子实例化 _keyBordHook = new KeyBordHook(); _keyBordHook.OnKeyDownEvent += kh_OnKeyDownEvent;
以上是关于winform使用钩子限制windows热键的主要内容,如果未能解决你的问题,请参考以下文章