tags:

views:

3259

answers:

4

How can I programmatically create an event that would simulate a key being pressed on the keyboard?

+7  A: 

I've not used it, but SendKeys may do what you want.

Use SendKeys to send keystrokes and keystroke combinations to the active application. This class cannot be instantiated. To send a keystroke to a class and immediately continue with the flow of your program, use Send. To wait for any processes started by the keystroke, use SendWait.

System.Windows.Forms.SendKeys.Send("A");
System.Windows.Forms.SendKeys.Send("{ENTER}");

Microsoft has some more usage examples here.

Michael Petrotta
I tried using SendKeys.Send and I get this InvalidOperationException:"SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method."Using SendKey.SendWait has no effect.
Dan Vogel
Make sure you're not sending the key event to yourself. Switch focus to the proper process before sending the event. The second linked article has some help on that.
Michael Petrotta
+5  A: 

Windows SendMessage API with send WM_KEYDOWN.

+13  A: 

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 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 proceed 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.

Ray Burns
I just tried your suggestion, I see no effect. I've attached a keyDown event handler to the focused element. The event I've raised is recieved, but the KeyState is None, the ScanCode is 0, and isDown is false. I assume I am getting these values because this is the actual state of the keyboard. Hitting a key on the actual keyboard, KeyState = Down, isDown=true, and ScanCode has a value.
Dan Vogel
Yes, KeyState=None and IsDown=false because they give the actual state of the keyboard. But KeyState, IsDown and ScanCode are not used anywhere in Microsoft's WPF code so unless you have some custom controls that use them it doesn't matter. Your problem is more likely that the code is looking for PreviewKeyDown instead of KeyDown, or it is using TextInput events, which are sent separately (for example, a TextBox uses TextInput events), or you want to invoke accelerators for which you need InputManager.ProcessEvent. But normally you don't want to do this.
Ray Burns
I edited my answer and added details on how to use TextInput events.
Ray Burns
This helps a lot. Thank you.
Dan Vogel
when I tried the first code of keydown I got error in "target" can't convert it to visual why?
salamonti
Dan, do you know how to emulate pressing a key with a modifier (ctrl/alt/shift) ? Particulary I need to simulate InputBinding:m_shell.InputBindings.Add( new KeyBinding(m_command, Key.Insert, ModifierKeys.Control | ModifierKeys.Alt));
Shrike
A: 

On the other hand, if you really do what to simulate actual keyboard keys for some >reason, you would use InputManager.ProcessInput() instead.

Thanks for a very useful post - I'm trying to use InputManager.ProcessInput() because I have an accelerator (CTRL) key I need to check. I am unclear about exactly how to do that - do you have a sample of the syntax I'd use?

EConnolly