作者: 张赐荣
.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
原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/273821.html