Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Modify keyboard key events"
description: Learn how to intercept a key press and modify which key is pressed on a Windows Forms .NET application.
ms.date: 04/02/2025
ms.date: 07/02/2026
ms.service: dotnet-desktop
ms.update-cycle: 365-days
dev_langs:
Expand All @@ -19,14 +19,14 @@ Windows Forms can consume and modify keyboard input. Consuming a key refers to h

## Consume a key

In a <xref:System.Windows.Forms.Control.KeyPress> event handler, set the <xref:System.Windows.Forms.KeyPressEventArgs.Handled%2A> property of the <xref:System.Windows.Forms.KeyPressEventArgs> class to `true`.
In a <xref:System.Windows.Forms.Control.KeyPress> event handler, set the <xref:System.Windows.Forms.KeyPressEventArgs.Handled*> property of the <xref:System.Windows.Forms.KeyPressEventArgs> class to `true`.

-or-

In a <xref:System.Windows.Forms.Control.KeyDown> event handler, set the <xref:System.Windows.Forms.KeyEventArgs.Handled%2A> property of the <xref:System.Windows.Forms.KeyEventArgs> class to `true`.
In a <xref:System.Windows.Forms.Control.KeyDown> event handler, set the <xref:System.Windows.Forms.KeyEventArgs.Handled*> property of the <xref:System.Windows.Forms.KeyEventArgs> class to `true`.

> [!NOTE]
> Setting the <xref:System.Windows.Forms.KeyEventArgs.Handled%2A> property in the <xref:System.Windows.Forms.Control.KeyDown> event handler doesn't prevent the <xref:System.Windows.Forms.Control.KeyPress> and <xref:System.Windows.Forms.Control.KeyUp> events from being raised for the current keystroke. Use the <xref:System.Windows.Forms.KeyEventArgs.SuppressKeyPress%2A> property for this purpose.
> Setting the <xref:System.Windows.Forms.KeyEventArgs.Handled*> property in the <xref:System.Windows.Forms.Control.KeyDown> event handler doesn't prevent the <xref:System.Windows.Forms.Control.KeyPress> and <xref:System.Windows.Forms.Control.KeyUp> events from being raised for the current keystroke. Use the <xref:System.Windows.Forms.KeyEventArgs.SuppressKeyPress*> property for this purpose.

The following example handles the <xref:System.Windows.Forms.Control.KeyPress> event to consume the `A` and `a` character keys. Those keys can't be typed into the text box:

Expand All @@ -35,7 +35,7 @@ The following example handles the <xref:System.Windows.Forms.Control.KeyPress> e

## Modify a standard character key

In a <xref:System.Windows.Forms.Control.KeyPress> event handler, set the <xref:System.Windows.Forms.KeyPressEventArgs.KeyChar%2A> property of the <xref:System.Windows.Forms.KeyPressEventArgs> class to the value of the new character key.
In a <xref:System.Windows.Forms.Control.KeyPress> event handler, set the <xref:System.Windows.Forms.KeyPressEventArgs.KeyChar*> property of the <xref:System.Windows.Forms.KeyPressEventArgs> class to the value of the new character key.

The following example handles the <xref:System.Windows.Forms.Control.KeyPress> event to change any `A` and `a` character keys to `!`:

Expand All @@ -44,9 +44,9 @@ The following example handles the <xref:System.Windows.Forms.Control.KeyPress> e

## Modify a non-character key

You can only modify non-character key presses by inheriting from the control and overriding the <xref:System.Windows.Forms.Control.PreProcessMessage%2A> method. As the input <xref:System.Windows.Forms.Message> is sent to the control, it's processed before the control raises events. You can intercept these messages to modify or block them.
You can only modify non-character key presses by inheriting from the control and overriding the <xref:System.Windows.Forms.Control.PreProcessMessage*> method. As the input <xref:System.Windows.Forms.Message> is sent to the control, it's processed before the control raises events. You can intercept these messages to modify or block them.

The following code example demonstrates how to use the <xref:System.Windows.Forms.Message.WParam%2A?displayProperty=nameWithType> property of the `m` parameter to change the key pressed. This code detects a key from <kbd>F1</kbd> through <kbd>F10</kbd> and translates the key into a numeric key ranging from <kbd>0</kbd> through <kbd>9</kbd> (where <kbd>F10</kbd> maps to <kbd>0</kbd>).
The following code example demonstrates how to use the <xref:System.Windows.Forms.Message.WParam*?displayProperty=nameWithType> property of the `m` parameter to change the key pressed. This code detects a key from <kbd>F1</kbd> through <kbd>F10</kbd> and translates the key into a numeric key ranging from <kbd>0</kbd> through <kbd>9</kbd> (where <kbd>F10</kbd> maps to <kbd>0</kbd>).

:::code language="csharp" source="snippets/how-to-change-key-press/csharp/NewTextBox.cs" id="PreProcessMessage":::
:::code language="vb" source="snippets/how-to-change-key-press/vb/NewTextBox.vb" id="PreProcessMessage":::
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Check which modifier key is pressed"
description: Learn how to detect when the SHIFT, ALT, or CTRL keys are pressed in Windows Forms for .NET.
ms.date: 04/02/2025
ms.date: 07/02/2026
ms.service: dotnet-desktop
ms.update-cycle: 365-days
dev_langs:
Expand Down Expand Up @@ -32,7 +32,7 @@ As the user types keys into your application, you can monitor for pressed modifi

If you handle the <xref:System.Windows.Forms.Control.KeyDown> event, the <xref:System.Windows.Forms.KeyEventArgs.Modifiers?displayProperty=nameWithType> property received by the event handler specifies which modifier keys are pressed. Also, the <xref:System.Windows.Forms.KeyEventArgs.KeyData?displayProperty=nameWithType> property specifies the character that was pressed along with any modifier keys combined with a bitwise OR.

If you're handling the <xref:System.Windows.Forms.Control.KeyPress> event or a mouse event, the event handler doesn't receive this information. Use the <xref:System.Windows.Forms.Control.ModifierKeys%2A> property of the <xref:System.Windows.Forms.Control> class to detect a key modifier. In either case, you must perform a bitwise AND of the appropriate <xref:System.Windows.Forms.Keys> value and the value you're testing. The <xref:System.Windows.Forms.Keys> enumeration offers variations of each modifier key, so it's important that you do the bitwise AND check with the correct value.
If you're handling the <xref:System.Windows.Forms.Control.KeyPress> event or a mouse event, the event handler doesn't receive this information. Use the <xref:System.Windows.Forms.Control.ModifierKeys*> property of the <xref:System.Windows.Forms.Control> class to detect a key modifier. In either case, you must perform a bitwise AND of the appropriate <xref:System.Windows.Forms.Keys> value and the value you're testing. The <xref:System.Windows.Forms.Keys> enumeration offers variations of each modifier key, so it's important that you do the bitwise AND check with the correct value.

For example, the following key values represent the <kbd>SHIFT</kbd> key:

Expand All @@ -45,7 +45,7 @@ The correct value to test <kbd>SHIFT</kbd> as a modifier key is <xref:System.Win

## Detect modifier key

Detect if a modifier key is pressed by comparing the <xref:System.Windows.Forms.Control.ModifierKeys%2A> property and the <xref:System.Windows.Forms.Keys> enumeration value with a bitwise AND operator.
Detect if a modifier key is pressed by comparing the <xref:System.Windows.Forms.Control.ModifierKeys*> property and the <xref:System.Windows.Forms.Keys> enumeration value with a bitwise AND operator.

The following code example shows how to determine whether the <kbd>SHIFT</kbd> key is pressed within the <xref:System.Windows.Forms.Control.KeyPress> and <xref:System.Windows.Forms.Control.KeyDown> event handlers.

Expand Down

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace %2A with * in this file.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Handle keyboard input at the Form level"
description: Learn how to handle keyboard input for your Windows Forms at the form level, before messages reach a control.
ms.date: 04/02/2025
ms.date: 07/01/2026
ms.service: dotnet-desktop
ms.update-cycle: 365-days
dev_langs:
Expand All @@ -19,11 +19,41 @@ Windows Forms provides the ability to handle keyboard messages at the form level

## Handle a keyboard message

Handle the <xref:System.Windows.Forms.Control.KeyPress> or <xref:System.Windows.Forms.Control.KeyDown> event of the active form and set the <xref:System.Windows.Forms.Form.KeyPreview%2A> property of the form to `true`. This property causes the keyboard to be received by the form before they reach any controls on the form. The following code example handles the <xref:System.Windows.Forms.Control.KeyPress> event by detecting all of the number keys and consuming <kbd>1</kbd>, <kbd>4</kbd>, and <kbd>7</kbd>.
Handle the <xref:System.Windows.Forms.Control.KeyPress> or <xref:System.Windows.Forms.Control.KeyDown> event of the active form and set the <xref:System.Windows.Forms.Form.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 <xref:System.Windows.Forms.Control.KeyPress> event by detecting all of the number keys and consuming <kbd>1</kbd>, <kbd>4</kbd>, and <kbd>7</kbd>.

:::code language="csharp" source="snippets/how-to-handle-forms/csharp/Form1.cs" id="HandleKey":::
:::code language="vb" source="snippets/how-to-handle-forms/vb/Form1.vb" id="HandleKey":::

## 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):

1. <xref:System.Windows.Forms.Control.ProcessCmdKey*>: Intercepts command keys such as menu shortcuts and accelerators. If this method returns `true`, the key is consumed and no event fires.
1. <xref:System.Windows.Forms.Control.IsInputKey*>: Determines whether a key should raise a <xref:System.Windows.Forms.Control.KeyDown> event or go to <xref:System.Windows.Forms.Control.ProcessDialogKey*>.
1. <xref:System.Windows.Forms.Control.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

- **<kbd>Enter</kbd> and <kbd>Escape</kbd>**: These keys might be handled by <xref:System.Windows.Forms.Form.AcceptButton*> and <xref:System.Windows.Forms.Form.CancelButton*> before reaching form events.
- **<kbd>Tab</kbd>**: 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 <xref:System.Windows.Forms.Control.ProcessCmdKey*> on your form. This runs during preprocessing, before standard form events.

:::code language="csharp" source="snippets/how-to-handle-forms/csharp/Form1.cs" id="ProcessCmdKey":::

:::code language="vb" source="snippets/how-to-handle-forms/vb/Form1.vb" id="ProcessCmdKey":::

For keys that should raise standard events in a specific control, use <xref:System.Windows.Forms.Control.PreviewKeyDown> with <xref:System.Windows.Forms.PreviewKeyDownEventArgs.IsInputKey*> set to `true` on that control.

## See also

- [Overview of using the keyboard](overview.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Simulate keyboard events"
description: Learn how to simulate keyboard events in Windows Forms for .NET.
ms.date: 04/02/2025
ms.date: 07/02/2026
ms.service: dotnet-desktop
ms.update-cycle: 365-days
dev_langs:
Expand All @@ -18,12 +18,12 @@ Windows Forms provides a few options for programmatically simulating keyboard in

## Use SendKeys

Windows Forms provides the <xref:System.Windows.Forms.SendKeys?displayProperty=fullName> class for sending keystrokes to the active application. There are two methods to send keystrokes to an application: <xref:System.Windows.Forms.SendKeys.Send%2A?displayProperty=nameWithType> and <xref:System.Windows.Forms.SendKeys.SendWait%2A?displayProperty=nameWithType>. The difference between the two methods is that `SendWait` blocks the current thread when the keystroke is sent, waiting for a response, while `Send` doesn't. For more information about `SendWait`, see [To send a keystroke to a different application](#to-send-a-keystroke-to-a-different-application).
Windows Forms provides the <xref:System.Windows.Forms.SendKeys?displayProperty=fullName> class for sending keystrokes to the active application. There are two methods to send keystrokes to an application: <xref:System.Windows.Forms.SendKeys.Send*?displayProperty=nameWithType> and <xref:System.Windows.Forms.SendKeys.SendWait*?displayProperty=nameWithType>. The difference between the two methods is that `SendWait` blocks the current thread when the keystroke is sent, waiting for a response, while `Send` doesn't. For more information about `SendWait`, see [To send a keystroke to a different application](#to-send-a-keystroke-to-a-different-application).

> [!CAUTION]
> If your application is intended for international use with various keyboards, the use of <xref:System.Windows.Forms.SendKeys.Send%2A?displayProperty=nameWithType> could yield unpredictable results and should be avoided.
> If your application is intended for international use with various keyboards, the use of <xref:System.Windows.Forms.SendKeys.Send*?displayProperty=nameWithType> could yield unpredictable results and should be avoided.

Behind the scenes, `SendKeys` uses an older Windows implementation for sending input, which might fail on Windows where it's expected that the application isn't running with administrative rights. If the older implementation fails, the code automatically tries the newer Windows implementation for sending input. Additionally, when the <xref:System.Windows.Forms.SendKeys> class uses the new implementation, the <xref:System.Windows.Forms.SendKeys.SendWait%2A> method no longer blocks the current thread when sending keystrokes to another application.
Behind the scenes, `SendKeys` uses an older Windows implementation for sending input, which might fail on Windows where it's expected that the application isn't running with administrative rights. If the older implementation fails, the code automatically tries the newer Windows implementation for sending input. Additionally, when the <xref:System.Windows.Forms.SendKeys> class uses the new implementation, the <xref:System.Windows.Forms.SendKeys.SendWait*> method no longer blocks the current thread when sending keystrokes to another application.

> [!IMPORTANT]
> If your application relies on consistent behavior regardless of the operating system, you can force the <xref:System.Windows.Forms.SendKeys> class to use the new implementation by adding the following application setting to your app.config file.
Expand All @@ -38,7 +38,7 @@ Behind the scenes, `SendKeys` uses an older Windows implementation for sending i

### To send a keystroke to the same application

Call the <xref:System.Windows.Forms.SendKeys.Send%2A?displayProperty=nameWithType> or <xref:System.Windows.Forms.SendKeys.SendWait%2A?displayProperty=nameWithType> method of the <xref:System.Windows.Forms.SendKeys> class. The specified keystrokes are received by the active control of the application.
Call the <xref:System.Windows.Forms.SendKeys.Send*?displayProperty=nameWithType> or <xref:System.Windows.Forms.SendKeys.SendWait*?displayProperty=nameWithType> method of the <xref:System.Windows.Forms.SendKeys> class. The specified keystrokes are received by the active control of the application.

The following code example uses `Send` to simulate pressing the <kbd>Alt</kbd> and <kbd>Down arrow</kbd> keys together. These keystrokes cause the <xref:System.Windows.Forms.ComboBox> control to display its dropdown. This example assumes a <xref:System.Windows.Forms.Form> with a <xref:System.Windows.Forms.Button> and <xref:System.Windows.Forms.ComboBox>.

Expand All @@ -47,13 +47,16 @@ The following code example uses `Send` to simulate pressing the <kbd>Alt</kbd> a

### To send a keystroke to a different application

The <xref:System.Windows.Forms.SendKeys.Send%2A?displayProperty=nameWithType> and <xref:System.Windows.Forms.SendKeys.SendWait%2A?displayProperty=nameWithType> methods send keystrokes to the active application, which is usually the application you're sending keystrokes from. To send keystrokes to another application, you first need to activate it. Because there's no managed method to activate another application, you must use native Windows methods to focus the other application. The following code example uses platform invoke to call the `FindWindow` and `SetForegroundWindow` methods to activate the Calculator application window, and then calls `Send` to issue a series of calculations to the Calculator application.
The <xref:System.Windows.Forms.SendKeys.Send*?displayProperty=nameWithType> and <xref:System.Windows.Forms.SendKeys.SendWait*?displayProperty=nameWithType> methods send keystrokes to the active application, which is usually the application you're sending keystrokes from. To send keystrokes to another application, you first need to activate it. Because there's no managed method to activate another application, you must use native Windows methods to focus the other application. The following code example uses platform invoke to call the `FindWindow` and `SetForegroundWindow` methods to activate the Calculator application window, and then calls `Send` to issue a series of calculations to the Calculator application.

The following code example uses `Send` to simulate pressing keys into the Windows Calculator application. It first searches for an application window with title of `Calculator` and then activates it. Once activated, the keystrokes are sent to calculate 10 plus 10.

:::code language="csharp" source="snippets/how-to-simulate-events/csharp/Form2.cs" id="Calculator":::
:::code language="vb" source="snippets/how-to-simulate-events/vb/Form2.vb" id="Calculator":::

> [!CAUTION]
> Window title lookup by name is locale-sensitive and can be brittle. Application windows might have localized or renamed titles depending on the system language and user configuration. This sample demonstrates a basic approach only and isn't recommended for production scenarios that need reliability across varied environments. For robust cross-application automation, consider using more reliable methods like window class identification or handle-based lookups, or prefer using UI automation frameworks designed for this purpose.

## Use OnEventName methods

The easiest way to simulate keyboard events is to call a method on the object that raises the event. Most events have a corresponding method that invokes them, named in the pattern of `On` followed by `EventName`, such as `OnKeyPress`. This option is only possible within custom controls or forms, because these methods are protected and can't be accessed from outside the context of the control or form.
Expand Down
Loading
Loading