鑑於 RegisterHotKey 穩定性優於鍵盤 Hook 且無額外系統開銷,採用 WinAPI 封裝。包含:TextBox 熱鍵輸入 UI、API 封裝類 (見第 2 篇)、自動解除重複 ID、表單關閉統一釋放。
Keys hotkeyVk = Keys.None;
private void txbHotKey_KeyDown(object sender, KeyEventArgs e)
{
txbHotKey.Text = string.Empty;
if (e.Control) txbHotKey.Text += "Ctrl+";
if (e.Alt) txbHotKey.Text += "Alt+";
if (e.Shift) txbHotKey.Text += "Shift+";
if (e.KeyCode >= Keys.A && e.KeyCode <= Keys.Z)
{
if (e.Modifiers != Keys.None) { txbHotKey.Text += e.KeyCode; hotkeyVk = e.KeyCode; }
}
else if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
{
if (e.Modifiers != Keys.None) { txbHotKey.Text += e.KeyCode.ToString().Substring(1); hotkeyVk = e.KeyCode; }
}
else if (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
{
if (e.Modifiers != Keys.None) { txbHotKey.Text += e.KeyCode.ToString().Replace("Pad", ""); hotkeyVk = e.KeyCode; }
}
else if (e.KeyCode >= Keys.F1 && e.KeyCode <= Keys.F12)
{
txbHotKey.Text += e.KeyCode; hotkeyVk = e.KeyCode;
}
e.SuppressKeyPress = false; e.Handled = true;
}
private void txbHotKey_KeyPress(object sender, KeyPressEventArgs e) => e.Handled = true;
private void txbHotKey_KeyUp(object sender, KeyEventArgs e) => CheckHotkey();
void txbHotKey_LostFocus(object sender, EventArgs e) => CheckHotkey();
private void CheckHotkey()
{
if (txbHotKey.Text.EndsWith("+") || txbHotKey.Text == string.Empty)
txbHotKey.Text = "無";
}
private void btnHotKey_Click(object sender, EventArgs e)
{
string hotkey = txbHotKey.Text.Replace("+", "");
if (hotkey != "無" && hotkey != string.Empty)
{
uint modifiers = 0;
if (hotkey.Contains("Ctrl")) { modifiers |= HotkeyHelper.MOD_CONTROL; hotkey = hotkey.Replace("Ctrl", ""); }
if (hotkey.Contains("Alt")) { modifiers |= HotkeyHelper.MOD_ALT; hotkey = hotkey.Replace("Alt", ""); }
if (hotkey.Contains("Shift")){ modifiers |= HotkeyHelper.MOD_SHIFT; hotkey = hotkey.Replace("Shift", ""); }
GameProvider.HotkeyHelper.RegisterHotKey(this.Handle, hotkeyId, modifiers, (uint)hotkeyVk);
}
}
KeyPress 設 Handled=true 避免字元輸入干擾。HotkeyHelper.RegisterHotKey。