HotkeyHelper 核心程式碼
using System;
using System.Collections.Generic;
namespace GFSucker.Game.Provider
{
public class HotkeyHelper : IDisposable
{
public const int MOD_ALT = 0x1;
public const int MOD_CONTROL = 0x2;
public const int MOD_SHIFT = 0x4;
public const int MOD_WIN = 0x8;
public const int WM_HOTKEY = 0x312;
private Dictionary dicHotkeys = new Dictionary();
public bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk)
{
if (dicHotkeys.ContainsKey(id))
{
if (dicHotkeys[id].IsRegistered)
{
WinApi.UnregisterHotKey(dicHotkeys[id].HWnd, id);
dicHotkeys[id].IsRegistered = false;
}
dicHotkeys[id].HWnd = hWnd;
}
else
{
dicHotkeys.Add(id, new Hotkey(hWnd, false));
}
dicHotkeys[id].IsRegistered = WinApi.RegisterHotKey(hWnd, id, fsModifiers, vk);
return dicHotkeys[id].IsRegistered;
}
private bool UnregisterHotKey(IntPtr hWnd, int id) => WinApi.UnregisterHotKey(hWnd, id);
#region Hotkey 資訊內部類
class Hotkey
{
public Hotkey(IntPtr hWnd, bool isRegistered) { _HWnd = hWnd; _IsRegistered = isRegistered; }
private IntPtr _HWnd; public IntPtr HWnd { get => _HWnd; set => _HWnd = value; }
private bool _IsRegistered; public bool IsRegistered { get => _IsRegistered; set => _IsRegistered = value; }
}
#endregion
#region IDisposable
public void Dispose()
{
foreach (int id in dicHotkeys.Keys)
if (dicHotkeys[id].IsRegistered)
UnregisterHotKey(dicHotkeys[id].HWnd, id);
}
#endregion
}
}
設計亮點
- 字典管理:
Dictionary<int, Hotkey> 以 ID 索引,支援多組熱鍵。
- 自動重註冊:同 ID 再次註冊時自動先解除舊註冊。
- IDisposable:
Dispose() 統一釋放所有已註冊熱鍵,配合 using 或表單關閉釋放。
- 修飾鍵常數:MOD_ALT/CONTROL/SHIFT/WIN 直接對應 WinAPI 定義。