Panel 默認 TabStop=false、不可聚焦,鍵盤消息發送給擁有焦點的控件 (通常是子控件或 Form)。若子控件不處理 Esc,事件不會冒泡到 Form。
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
const int WM_KEYDOWN = 0x100;
const int WM_SYSKEYDOWN = 0x104;
if (msg.Msg == WM_KEYDOWN || msg.Msg == WM_SYSKEYDOWN) {
if (keyData == Keys.Escape) {
this.Close(); // 或執行自定義邏輯
return true; // 標記已處理
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
ProcessCmdKey 在消息分發給控件**之前**調用,屬於「命令鍵」預處理,優先級最高。true 表示已處理,阻止後續分發;false 繼續正常流程。WM_KEYDOWN (0x100) 和 WM_SYSKEYDOWN (0x104, Alt 組合鍵) 覆蓋所有按鍵下壓。this.KeyPreview = true; // Form 優先接收鍵盤事件
private void MainForm_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Escape) { this.Close(); e.Handled = true; }
}
KeyPreview 使 Form 在子控件前收到 KeyDown/Up/Press,但不捕獲系統命令鍵 (如 Alt+F4),ProcessCmdKey 更徹底。