如何以编程方式在C#中生成按键事件?

Dan*_*gel 104 .net c# wpf keyboard-events

如何以编程方式创建一个模拟键盘上按键的事件?

Ray*_*rns 144

问题是标记为WPF,但到目前为止的答案是特定的WinForms和Win32.

要在WPF中执行此操作,只需构造一个KeyEventArgs并在目标上调用RaiseEvent.例如,要将Insert键KeyDown事件发送到当前关注的元素:

  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 }
  );
Run Code Online (Sandbox Code Playgroud)

此解决方案不依赖于本机调用或Windows内部,并且应该比其他解决方案更可靠.它还允许您模拟特定元素上的按键.

请注意,此代码仅适用于PreviewKeyDown,KeyDown,PreviewKeyUp和KeyUp事件.如果你想发送TextInput事件,你会这样做:

  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 }
  );
Run Code Online (Sandbox Code Playgroud)

另请注意:

  • 控件期望接收预览事件,例如,PreviewKeyDown应该在KeyDown之前

  • 使用target.RaiseEvent(...)将事件直接发送到目标,而不进行加速器,文本组合和IME等元处理.这通常是你想要的.另一方面,如果由于某种原因你真的要模拟实际的键盘键,你可以使用InputManager.ProcessInput()代替.

  • 当我尝试第一个keydown代码时,我在"目标"中得到错误无法将其转换为可视化为什么? (21认同)
  • 关于_target_问题,我使用`Keyboard.PrimaryDevice.ActiveSource`进行了解决,请参阅http://stackoverflow.com/questions/10820990/how-to-create-a-keyeventargs-object-in-wpf-related-to -a那么答案/ 10821212#10821212 (13认同)
  • Dan,你知道如何用一个修改器(ctrl/alt/shift)模拟按键吗?特别是我需要模拟InputBinding:m_shell.InputBindings.Add(new KeyBinding(m_command,Key.Insert,ModifierKeys.Control | ModifierKeys.Alt)); (3认同)
  • 这个答案非常好,但它不能用于发送带修饰符的键,正如@Shrike所说.(例如`Ctrl + C`.) (3认同)

小智 26

要在没有Windows窗体上下文的情况下生成关键事件,我们可以使用以下方法,

[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
Run Code Online (Sandbox Code Playgroud)

示例代码如下:

const int VK_UP = 0x26; //up key
const int VK_DOWN = 0x28;  //down key
const int VK_LEFT = 0x25;
const int VK_RIGHT = 0x27;
const uint KEYEVENTF_KEYUP = 0x0002;
const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
int press()
{
    //Press the key
    keybd_event((byte)VK_UP, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

虚拟键列表在此处定义.

要获得完整的图片,请使用以下链接, http://tksinghal.blogspot.in/2011/04/how-to-press-and-hold-keyboard-key.html


Mic*_*tta 22

我没有用它,但SendKeys可能会做你想要的.

使用SendKeys将键击和击键组合发送到活动应用程序.此类无法实例化.要将键击发送到类并立即继续执行程序流程,请使用"发送".要等待击键启动的任何进程,请使用SendWait.

System.Windows.Forms.SendKeys.Send("A");
System.Windows.Forms.SendKeys.Send("{ENTER}");
Run Code Online (Sandbox Code Playgroud)

Microsoft 在此处提供了更多用法示例.

  • 我尝试使用SendKeys.Send并得到此InvalidOperationException:"SendKeys无法在此应用程序中运行,因为应用程序未处理Windows消息.要么更改应用程序以处理消息,要么使用SendKeys.SendWait方法." 使用SendKey.SendWait无效. (3认同)

Rav*_*erg 10

容易!(因为其他人已经为我们做了工作......)

花了很多时间用建议的答案尝试这个后,我遇到了这个codeplex项目Windows输入模拟器,这使得它很简单,可以模拟按键:

  1. 安装包,可以完成,也可以从NuGet包管理器或包管理器控制台中完成,如:

    Install-Package InputSimulator

  2. 使用这两行代码:

    inputSimulator = new InputSimulator() inputSimulator.Keyboard.KeyDown(VirtualKeyCode.RETURN)

就是这样!