Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Windows Forms provides the ability to handle keyboard messages at the form level, before the messages reach a control. This article shows how to accomplish this task.
Handle a keyboard message
Handle the KeyPress or KeyDown event of the active form and set the KeyPreview property of the form to true. This property causes keyboard input to reach the form before it reaches any controls on the form. The following code example handles the KeyPress event by detecting all of the number keys and consuming 1, 4, and 7.
// Detect all numeric characters at the form level and consume 1, 4, and 7.
// Form.KeyPreview must be set to true for this event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsDigit(e.KeyChar))
{
MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.");
switch (e.KeyChar)
{
case '1':
case '4':
case '7':
MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.");
e.Handled = true;
break;
}
}
}
' Detect all numeric characters at the form level and consume 1, 4, and 7.
' Form.KeyPreview must be set to true for this event handler to be called.
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs)
If Char.IsDigit(e.KeyChar) Then
MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.")
Select Case e.KeyChar
Case "1"c, "4"c, "7"c
MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.")
e.Handled = True
End Select
End If
End Sub
When KeyPreview is not enough
Setting Form.KeyPreview = true doesn't guarantee that every key reaches form-level event handlers. Certain keys go through preprocessing before standard form events run. Understanding these exceptions is important for handling command keys, dialog keys, and control-specific input correctly.
Command and dialog key preprocessing
Before form-level keyboard events fire, Windows preprocesses certain keys through these methods (in order):
- ProcessCmdKey: Intercepts command keys such as menu shortcuts and accelerators. If this method returns
true, the key is consumed and no event fires. - IsInputKey: Determines whether a key should raise a KeyDown event or go to ProcessDialogKey.
- ProcessDialogKey: Handles navigation keys (Escape, Tab, Return, and arrow keys). If processed, no event fires.
If a focused control consumes a key during preprocessing, the form never receives it, regardless of KeyPreview.
Special cases that bypass form-level handlers
- Enter and Escape: These keys might be handled by AcceptButton and CancelButton before reaching form events.
- Tab: Often consumed by control focus management and won't reach form handlers.
- Menu shortcuts: Alt key combinations are handled by menu preprocessing.
Intercept command keys at the form level
To handle command keys (including menu shortcuts and dialog keys) at the form level, override ProcessCmdKey on your form. This runs during preprocessing, before standard form events.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// Intercept Ctrl+A for custom handling
if (keyData == (Keys.Control | Keys.A))
{
MessageBox.Show("Ctrl+A intercepted at form level");
return true; // Mark as handled
}
// Pass other keys to the base handler
return base.ProcessCmdKey(ref msg, keyData);
}
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
' Intercept Ctrl+A for custom handling
If keyData = (Keys.Control Or Keys.A) Then
MessageBox.Show("Ctrl+A intercepted at form level")
Return True ' Mark as handled
End If
' Pass other keys to the base handler
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
For keys that should raise standard events in a specific control, use PreviewKeyDown with IsInputKey set to true on that control.
See also
.NET Desktop feedback