承接上篇,本文說明如何在 C# 中註冊系統熱鍵(RegisterHotKey),並在熱鍵觸發時取得前景視窗標題,作為攔截彈出視窗的判斷依據。
// 表單載入時註冊 Ctrl+Shift+J
private const int HOTKEY_ID = 100;
private void Form1_Load(object sender, EventArgs e)
{
bool success = RegisterHotKey(this.Handle, HOTKEY_ID,
KeyModifiers.Control | KeyModifiers.Shift, Keys.J);
if (!success) MessageBox.Show("熱鍵註冊失敗,可能已被佔用。");
}
// 表單關閉時解除註冊
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
UnregisterHotKey(this.Handle, HOTKEY_ID);
}
// P/Invoke 宣告
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[Flags]
private enum KeyModifiers : uint
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8
}
覆寫 WndProc 攔截 WM_HOTKEY(0x0312):
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312 && m.WParam.ToInt32() == HOTKEY_ID)
{
ProcessHotkey();
}
base.WndProc(ref m);
}
private void ProcessHotkey()
{
IntPtr hwnd = GetForegroundWindow();
if (hwnd != IntPtr.Zero)
{
StringBuilder sb = new StringBuilder(256);
GetWindowText(hwnd, sb, sb.Capacity);
string title = sb.ToString();
if (!string.IsNullOrEmpty(title))
{
// 將標題加入列表或進行比對
listView1.Items.Add(title);
}
}
}
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
GlobalAddAtom 產生全域唯一 ID。Control | Shift 等於 6,需與虛擬鍵碼(Keys.J = 0x4A)一起傳遞。uiAccess 清單。掌握 RegisterHotKey 與 GetForegroundWindow/GetWindowText 的搭配,即可在 C# 輕鬆實作全域熱鍵觸發的視窗標題擷取,為彈出視窗攔截、快速截圖、記事本呼叫等工具奠定基礎。