作者: 张赐荣
.NET 类库本身没有封装注册全局快捷键的函数,想要实现注册全局热键,就需要使用Win32API。
在WinAPI中,注册和注销全局快捷键分别通过registerhotkey和unregisterhotkey函数实现。
注册快捷键后,还需要重写窗口过程函数。
以下代码封装了全局快捷键注册功能 (在 Winform 项目中测试通过)
=代码开始=
using System;
using System.Runtime.InteropServices;
namespace CRHotkey
{
	internal delegate IntPtr WNDProc(IntPtr hwnd, uint messageID, IntPtr WParam, IntPtr LParam);
	public delegate void HotkeyEventHandler(Object sender, HotkeyInfo ea);
	public static class Hotkey
	{
		private const int GWL_WNDPROC = (-4);
		private const uint WM_HOTKEY = 0x0312;
		private static readonly IntPtr HWND = IntPtr.Zero;
		private static readonly IntPtr DEFWndProc = IntPtr.Zero;
		public static event HotkeyEventHandler HotkeyPressed;
		[DllImport("user32.dll", EntryPoint = "RegisterHotKey")]
		private static extern bool API_RegisterHotKey(IntPtr hWnd, uint id, uint fsModifiers, uint vk);
		[DllImport("user32.dll", EntryPoint = "UnregisterHotKey")]
		private static extern bool API_UnregisterHotKey(IntPtr hWnd, uint id);
		[DllImport("user32.dll", EntryPoint = "CallWindowProc")]
		private static extern IntPtr API_CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
		[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
		private static extern IntPtr API_SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
		static Hotkey()
		{
			HWND = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
			DEFWndProc = API_SetWindowLong(HWND, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(new WNDProc(UDFWndProc)));
		}
		private static IntPtr UDFWndProc(IntPtr hwnd, uint msgID, IntPtr WParam, IntPtr LParam)
		{
			if (msgID == WM_HOTKEY)
			{
				byte[] bit32 = BitConverter.GetBytes(LParam.ToInt32());
				uint hkid = Convert.ToUInt32(WParam.ToInt32());
				uint mk = BitConverter.ToUInt16(bit32, 0);
				uint key = BitConverter.ToUInt16(bit32, 2);
				HotkeyInfo ki = new HotkeyInfo(hkid, mk, key);
				HotkeyPressed?.Invoke(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle, ki);
			}
			return (API_CallWindowProc(DEFWndProc, hwnd, msgID, WParam, LParam));
		}
		public static bool RegisterHotkey(uint hotkeyID, ModifierKeys mk, VirtualKey vk)
		{
			try
			{
				bool res = API_RegisterHotKey(HWND, hotkeyID, ((uint)mk), ((uint)vk));
				return (res);
			}
			catch (Exception ex)
			{
				return (false);
			}
		}
		public static bool UnregisterHotkey(uint hotkeyID)
		{
			try
			{
				bool res = API_UnregisterHotKey(HWND, hotkeyID);
				return (res);
			}
			catch (Exception ex)
			{
				return (false);
			}
		}
	}
	public class HotkeyInfo : EventArgs
	{
		private uint _HotkeyID = 0;
		public uint HotkeyID { get => this._HotkeyID; }
		private ModifierKeys _ModifierKeys = ModifierKeys.None;
		public ModifierKeys ModifierKeys { get => this._ModifierKeys; }
		private VirtualKey _Key = VirtualKey.None;
		public VirtualKey Key { get => this._Key; }
		public HotkeyInfo(uint hotkeyID, uint mk, uint vk)
		{
			this._HotkeyID = hotkeyID;
			this._ModifierKeys = (ModifierKeys)mk;
			this._Key = (VirtualKey)vk;
		}
	}
	[Flags()]
	public enum ModifierKeys : uint
	{
		None = 0,
		Alt = 1,
		Ctrl = 2,
		Shift = 4,
		WinKey = 8,
	}
	public enum VirtualKey : uint
	{
		None = 0,
		BackSpace = 8,
		Tab = 9,
		Clear = 12,
		Enter = 13,
		Pause = 19,
		CapsLock = 20,
		Escape = 27,
		Space = 32,
		PageUp = 33,
		PageDown = 34,
		End = 35,
		Home = 36,
		Left = 37,
		Up = 38,
		Right = 39,
		Down = 40,
		PrintScreen = 44,
		Insert = 45,
		Delete = 46,
		Help = 47,
		Key0 = 48,
		Key1 = 49,
		Key2 = 50,
		Key3 = 51,
		Key4 = 52,
		Key5 = 53,
		Key6 = 54,
		Key7 = 55,
		Key8 = 56,
		Key9 = 57,
		A = 65,
		B = 66,
		C = 67,
		D = 68,
		E = 69,
		F = 70,
		G = 71,
		H = 72,
		I = 73,
		J = 74,
		K = 75,
		L = 76,
		M = 77,
		N = 78,
		O = 79,
		P = 80,
		Q = 81,
		R = 82,
		S = 83,
		T = 84,
		U = 85,
		V = 86,
		W = 87,
		X = 88,
		Y = 89,
		Z = 90,
		Application = 93,
		Sleep = 95,
		NumPad0 = 96,
		NumPad1 = 97,
		NumPad2 = 98,
		NumPad3 = 99,
		NumPad4 = 100,
		NumPad5 = 101,
		NumPad6 = 102,
		NumPad7 = 103,
		NumPad8 = 104,
		NumPad9 = 105,
		Multiply = 106,
		Add = 107,
		Separator = 108,
		Subtract = 109,
		Decimal = 110,
		Divide = 111,
		F1 = 112,
		F2 = 113,
		F3 = 114,
		F4 = 115,
		F5 = 116,
		F6 = 117,
		F7 = 118,
		F8 = 119,
		F9 = 120,
		F10 = 121,
		F11 = 122,
		F12 = 123,
		NumLock = 144,
		Scroll = 145,
		Semicolon = 186,
		Equals = 187,
		Comma = 188,
		Minus = 189,
		Dot = 190,
		Slash = 191,
		BackQuote = 192,
		LeftBracket = 219,
		BackSlash = 220,
		RightBracket = 211,
		Quote = 222,
	}
}
=代码结束=
这是关于c#实现全局快捷键函数的文章。
我希望它能帮助你学习。
推荐阅读 《在 WinForms 项目中使用全局快捷键》: https://chowdera.com/2022/02/202202191319103608.html
知乎: @张赐荣
赐荣博客: www.prc.cx
 
                    
                 
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号