How can I programmatically generate keypress events in C#?
The question is tagged WPF but the answers so far are specific WinForms and Win32.
To do this in WPF, simply construct a KeyEventArgs and call RaiseEvent on the target. For example, to send an Insert key KeyDown event to the currently focused element:
var key = Key.Insert; // Key to send
var target = Keyboard.FocusedElement; // Target element
var routedEvent = Keyboard.KeyDownEvent; // Event to send
target.RaiseEvent(
new KeyEventArgs(
Keyboard.PrimaryDevice,
PresentationSource.FromVisual(target),
0,
key)
{ RoutedEvent=routedEvent }
);
This solution doesn't rely on native calls or Windows internals and should be much more reliable than the others. It also allows you to simulate a keypress on a specific element.
Note that this code is only applicable to PreviewKeyDown, KeyDown, PreviewKeyUp, and KeyUp events. If you want to send TextInput events you'll do this instead:
var text = "Hello";
var target = Keyboard.FocusedElement;
var routedEvent = TextCompositionManager.TextInputEvent;
target.RaiseEvent(
new TextCompositionEventArgs(
InputManager.Current.PrimaryKeyboardDevice,
new TextComposition(InputManager.Current, target, text))
{ RoutedEvent = routedEvent }
);
Also note that:
Controls expect to receive Preview
events, for example PreviewKeyDown
should precede KeyDownUsing target.RaiseEvent(...) sends the event directly to the target
without meta-processing such as
accelerators, text composition and
IME. This is normally what you want.
On the other hand, if you really do
what to simulate actual keyboard keys
for some reason, you would use
InputManager.ProcessInput() instead.
Trigger a keyboard key press event without pressing the key from keyboard
System.Windows.Forms.SendKeys.Send()
has done the trick for me.
For advanced instructions and the list of available codes, consult the docs for the method.
For example, to send Shift+A I used SendKeys.Send("+(a)")
.
How to programmatically trigger key press events in WinRT/C#/XAML?
It is not allowed to programmatically trigger a user-initiated event in WinRT XAML. The reason is, some API is restricted to be called only by user interaction. Programmatically causing such events would bypass this security mechanism.
Programmatically generate keydown presses for WPF unit tests
Figured this out after reading this post.
Basically, you need to put your control inside a Window and call Window.Show() on it. The post mentioned an WPF bug, but I didn't encounter this in WPF 4.
After calling Window.Show(), the presentation source will no longer be null and you will be able to send keys to the control.
C# - trigger key down event for active control
You can't use the SendKeys
class for that, unfortunately. You will need to go to a lower level API.
Poking a window with a keydown message
In Windows, keyboard events are sent to windows and controls via the Windows message pump. A piece of code using PostMessage should do the trick:
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
const uint WM_KEYDOWN = 0x0100;
void SendKeyDownToProcess(string processName, System.Windows.Forms.Keys key)
{
Process p = Process.GetProcessesByName(processName).FirstOrDefault();
if (p != null)
{
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (int)key, 0);
}
}
Note that the application receiving these events may not do anything with it until a corresponding WM_KEYUP
is received. You can get other message constants from here.
Poking a control other than the main window
The above code will send a keydown to the "MainWindowHandle." If you need to send it to something else (e.g. the active control) you will need to call PostMessage
with a handle other than p.MainWindowHandle
. The question is... how do you get that handle?
This is actually very involved... you will need to temporarily attach your thread to the window's message input and poke it to figure out what the handle is. This can only work if the current thread exists in a Windows Forms application and has an active message loop.
An explanation can be found here, as well as this example:
using System.Runtime.InteropServices;
public partial class FormMain : Form
{
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
static extern IntPtr AttachThreadInput(IntPtr idAttach,
IntPtr idAttachTo, bool fAttach);
[DllImport("user32.dll")]
static extern IntPtr GetFocus();
public FormMain()
{
InitializeComponent();
}
private void timerUpdate_Tick(object sender, EventArgs e)
{
labelHandle.Text = "hWnd: " +
FocusedControlInActiveWindow().ToString();
}
private IntPtr FocusedControlInActiveWindow()
{
IntPtr activeWindowHandle = GetForegroundWindow();
IntPtr activeWindowThread =
GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero);
IntPtr thisWindowThread = GetWindowThreadProcessId(this.Handle, IntPtr.Zero);
AttachThreadInput(activeWindowThread, thisWindowThread, true);
IntPtr focusedControlHandle = GetFocus();
AttachThreadInput(activeWindowThread, thisWindowThread, false);
return focusedControlHandle;
}
}
The good news-- if SendKeys
worked for you, then you might not need to do all this-- SendKeys
also sends messages to the main window handle.
How to simulate key press event?
So... In case anybody is interested.
- InvokeMember doesnt have anything for key pressing.
- Its impossible to send keys to the control.
- There is a way to "send keys" using iQuery which... is fake and poorly-designed. It doesnt help in my case. And when it does "send key", "InvokeMember("OnKeyUp")" works as well.
What is possible? Its possible to send keys to a window... Teoretically its possible to send keys to unactive window(using SendMessage() and PostMessage()), but practically nobody has successfully done this since WinXP & x32 times...
I didnt try myself, but there are people who was able to send keys using "SendInput". But this useless anyway, cause the function can only send keys to active window.
So... SendKeys.Send(which, i guess, is a wrapper for SendInput) is still the best way around.
Solution
I created a form(window) for my webbrowser control. I initialize it, but dont use "Show". Then i simply make this form active right before "SendKeys.Send"(dont forget to focus on both element(inside the control) and control(inside the form) as well). Since there is no form to show, user doesnt notice anything and keys go to the right window. If its needed, its possible to save the handle of window which was active previously and make it active again after the sending(so focus wont be lost).
Summary
Although im ok with this solution and i will use it, its far from perfect... If anybody finds something better, please let me know(even in distant future).
Programmatically Simulate a KeyDown Event for RichTextBox in C# 2010
The RichTextBox
has an Undo
method that will do the same thing as CTRL+Z. You can call that when clicking the ToolStribButton
. There are also Copy
and Paste
methods along with a CanPaste
method that can be used for enabling/disabling the ToolStripButton
corresponding to the paste command.
This way you don't need to simulate anything but instead call the functionality that produces the behavior. After all, the key presses are just triggers for that behavior.
Enter key press in C#
Try this code,might work (Assuming windows form):
private void CheckEnter(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
// Enter key pressed
}
}
Register the event like this :
this.textBox1.KeyPress += new
System.Windows.Forms.KeyPressEventHandler(CheckEnter);
Related Topics
When to Use Cast() and Oftype() in Linq
Reading Email Using Pop3 in C#
Compiling/Executing a C# Source File in Command Prompt
Why Does My .Net 4 Application Know .Net 4 Is Not Installed
Binding a Button's Visibility to a Bool Value in Viewmodel
What Guarantees Are There on the Run-Time Complexity (Big-O) of Linq Methods
Difference Between Ref and Out Parameters in .Net
How to Set Processor Affinity to a Thread or a Task in .Net
Execute C# Code at Runtime from Code File
How to Get JSON.Net to Serialize Members of a Class Deriving from List<T>
Show a Form Without Stealing Focus
Get a Screenshot of a Specific Application
Calling Async Method Synchronously
C# Splitting Strings on '#' Character
Inner Join of Datatables in C#
Password Protect a SQLite Db. Is It Possible