在 Windows Forms 中,使用者輸入會以 Windows 訊息的形式傳送至應用程式。 有一系列的可覆寫方法會在應用程式、表單和控制層級處理這些訊息。 這些方法在接收到鍵盤訊息時就會引發事件,而這些事件經處理後將可取得鍵盤輸入的相關資訊。 在許多情況下,Windows Forms 應用程式只要處理這些事件,就能處理所有用戶輸入。 在其他情況下,應用程式可能需要覆寫處理訊息的其中一種方法,以便在應用程式、表單或控件收到訊息之前攔截特定訊息。
鍵盤事件
所有 Windows Forms 控制項都會繼承一組與滑鼠和鍵盤輸入相關的事件。 例如,控制項可以處理 KeyPress 事件以確定按下的按鍵的字元碼。 如需詳細資訊,請參閱使用鍵盤事件。
處理使用者輸入訊息的方法
表單和控制項可以存取 IMessageFilter 介面和一組可覆寫的方法,以處理訊息佇列中不同點位的 Windows 訊息。 這些方法都有 Message 參數,會封裝 Windows 訊息的低階詳細資料。 您可以實作或覆寫這些方法以檢查訊息,然後取用訊息或將其傳遞給訊息佇列中的下一個取用者。 下表顯示處理 Windows Forms 中所有 Windows 訊息的方法。
| 方法 | 註釋 |
|---|---|
| PreFilterMessage | 此方法會攔截已在應用層級排入佇列 (也稱為已發佈) 的 Windows 訊息。 |
| PreProcessMessage | 此方法會在 Windows 訊息進行處理之前,在表單和控制項層級加以攔截。 |
| WndProc | 此方法會在表單和控制項層級處理 Windows 訊息。 |
| DefWndProc | 此方法會在表單和控制層級執行 Windows 訊息的預設處理。 這會提供視窗的基本功能。 |
| OnNotifyMessage | 此方法會在訊息進行處理之後,在表單和控制項層級加以攔截。 必須設定 EnableNotifyMessage 樣式位元,才能呼叫此方法。 |
鍵盤和滑鼠訊息是由一組額外的可覆寫方法來處理,這些方法是那些訊息類型特有的。 如需詳細資訊,請參閱前置處理按鍵一節。
金鑰的類型
Windows Forms 會將鍵盤輸入視為由位元 Keys 列舉代表的虛擬按鍵碼。 使用 Keys 列舉,您可以結合一系列已按下的按鍵來產生單一值。 這些值對應於伴隨 WM_KEYDOWN 和 WM_SYSKEYDOWN 訊息的值。 您可以藉由處理 KeyDown 或 KeyUp 事件來偵測大部分的實體按鍵操作。 字元按鍵是 Keys 列舉的子集,並對應至伴隨 WM_CHAR 和 WM_SYSCHAR 訊息的值。 如果按下的按鍵組合產生了字元,您可以藉由處理 KeyPress 事件來偵測字元。 或者,您可以使用 Keyboard (由 Visual Basic 程式設計介面所公開) 來探索哪些按鍵已按下及傳送按鍵。 如需詳細資訊,請參閱存取鍵盤(Visual Basic)。
鍵盤事件的順序
如先前所列,控件上可能會發生三個鍵盤相關事件。 下列序列顯示事件的一般順序︰
- 使用者按下 A 鍵,按鍵會進行預處理、分派,然後發生 KeyDown 事件。
- 使用者按住 A 鍵,按鍵會被預先處理、分派,然後KeyPress事件發生。 當使用者按住一個按鍵時,此事件會發生很多次。
- 用戶釋放 A 鍵、金鑰會預先處理、分派和 KeyUp 事件發生。
前置處理按鍵
如同其他訊息,鍵盤訊息會在表單或控制項的 WndProc 方法中進行處理。 不過,在處理鍵盤訊息之前,PreProcessMessage 方法會呼叫一或多個可覆寫的方法,以處理特殊字元按鍵與實體按鍵。 您可以重寫這些方法,以便在控件處理訊息之前偵測和篩選特定鍵。 下表顯示正在執行的動作以及發生的相關方法 (依方法的發生順序顯示)。
KeyDown 事件前置處理
| 行動 | 相關方法 | 註釋 |
|---|---|---|
| 檢查命令按鍵,例如快速鍵或功能表捷徑。 | ProcessCmdKey | 這個方法會處理命令按鍵,其優先於一般按鍵。 如果此方法傳 true回 ,則不會分派密鑰訊息,而且不會發生索引鍵事件。 如果傳回 false,則會呼叫 IsInputKey. |
| 檢查需要前置處理的特殊按鍵,或應該引發 KeyDown 事件並分派至控制項的標準字元按鍵。 | IsInputKey | 如果此方法傳回 true,則表示控制項是一般字元並且引發 KeyDown 事件。 若為 false,則會呼叫 ProcessDialogKey。 注意:若要確保控制項會取得按鍵或按鍵組合,您可以處理 PreviewKeyDown 事件,並且為您要的一或多個按鍵將 PreviewKeyDownEventArgs 的 IsInputKey 設定為 true。 |
| 檢查導覽鍵 (ESC、TAB、Return 或方向鍵)。 | ProcessDialogKey | 這個方法會處理運用控制項內特殊功能的實體按鍵,例如在控制項與其父代之間切換焦點。 如果直接的控制項未處理該鍵,則會在父控制項上呼叫ProcessDialogKey,並依此類推,呼叫至階層中最上層的控制項。 如果這個方法傳 true回 ,則前置處理已完成,而且不會產生索引鍵事件。 如果傳回 false,就會發生 KeyDown 事件。 |
KeyPress 事件的前置處理
| 行動 | 相關方法 | 註釋 |
|---|---|---|
| 查看按鍵是否為應由控制項處理的標準字元 | IsInputChar | 如果此字元是標準字元,這個方法會傳回 true,就會引發 KeyPress 事件,而且不會發生任何進一步的前置處理。 否則 ProcessDialogChar 被呼叫。 |
| 查看此字元是否為助憶鍵 (例如按鈕上 &OK) | ProcessDialogChar | 這個方法類似於 ProcessDialogKey,會呼叫控件階層。 如果控制項是容器控制項,它會藉由對本身與其子控制項呼叫 ProcessMnemonic 來檢查助憶鍵。 如果 ProcessDialogChar 傳 true回 , KeyPress 則不會發生事件。 |
處理鍵盤訊息
鍵盤訊息到達 WndProc 表單或控件的方法之後,會由一組可覆寫的方法進行處理。 每種方法都會傳回 Boolean 值,以指定控制項是否已處理和取用鍵盤訊息。 如果其中一個方法傳 true回 ,則會將訊息視為已處理,而且不會傳遞至控件的基底或父代,以便進一步處理。 否則,訊息會保留在訊息佇列中,可能會在控制項的基底或父物件的另一個方法中被處理。 下表顯示處理鍵盤訊息的方法。
| 方法 | 註釋 |
|---|---|
| ProcessKeyMessage | 此方法會處理控制項的 WndProc 方法收到的所有鍵盤訊息。 |
| ProcessKeyPreview | 此方法會將鍵盤訊息傳送至控制項的父代。 如果 ProcessKeyPreview 傳回 true,則不會產生任何索引鍵事件,否則會呼叫 ProcessKeyEventArgs。 |
| ProcessKeyEventArgs | 此方法會視需要引發 KeyDown、KeyPress 和 KeyUp 事件。 |
覆寫鍵盤方法
在鍵盤訊息被預處理和處理時,有許多方法可以用來覆寫;然而,某些方法比其他方法更為適合。 下表顯示您可能想要完成的工作,以及覆寫鍵盤方法的最佳方式。 如需覆寫方法的詳細資訊,請參閱繼承 (C# 程式設計手冊) 或繼承 (Visual Basic)
| 任務 | 方法 |
|---|---|
| 攔截瀏覽鍵並引發 KeyDown 事件。 例如,您想要在文字框中處理 Tab 和 Enter 。 | 覆寫 IsInputKey。 或者,您可以處理PreviewKeyDown 事件,並將IsInputKey的PreviewKeyDownEventArgs設置為true,適用於您想要的鍵或按鍵。 |
| 在控制項上執行特殊輸入或導覽處理。 例如,您想使用清單控制項中的方向鍵來變更所選的項目。 | 覆寫 ProcessDialogKey |
| 攔截瀏覽鍵並引發 KeyDown 事件。 例如,在微調方塊控制項中,您想要多次按方向鍵以加快項目的進度。 | 覆寫 IsInputKey。 |
| 在 KeyPress 事件期間執行特殊輸入或瀏覽處理。 例如,在列表控制中,按住 R 鍵會跳至以字母 r 開頭的項目。 | 覆寫 ProcessDialogKey |
| 執行自訂助憶鍵處理;例如,您想要處理工具列內含主控描繪按鈕上的助憶鍵。 | 覆寫 IsInputKey。 |