How to Programmatically Generate Keypress Events in C#

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 KeyDown

  • Using 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.

  1. InvokeMember doesnt have anything for key pressing.
  2. Its impossible to send keys to the control.
  3. 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



Leave a reply



Submit