如何模拟键盘事件

Windows 窗体提供了一些用于以编程方式模拟键盘输入的选项。 本文概述了这些选项。

使用 SendKeys

Windows 窗体提供 System.Windows.Forms.SendKeys 类用于将击键发送到活动应用程序。 有两种方法可将击键发送到应用程序: SendKeys.SendSendKeys.SendWait。 这两种方法之间的差异在于, SendWait 在发送击键时阻止当前线程,等待响应,而 Send 不会。 要了解更多关于SendWait的信息,请参阅将击键发送到其他应用程序

谨慎

如果应用程序旨在通过各种键盘进行国际使用,则使用 SendKeys.Send 可能会产生不可预知的结果,应避免使用。

在后台,SendKeys 使用旧版Windows实现来发送输入,而这种方式可能会在未以管理员权限运行应用程序的Windows系统上失败。 如果旧实现失败,代码会自动尝试较新的 Windows 实现来发送输入。 此外,当 SendKeys 类使用新实现时,SendWait 方法在向另一个应用程序发送击键时不再阻塞当前线程。

重要

如果应用程序依赖于一致的行为,无论操作系统如何,都可以通过向 app.config 文件添加以下应用程序设置来强制 SendKeys 类使用新实现。

<appSettings>
  <add key="SendKeys" value="SendInput"/>
</appSettings>

若要强制 SendKeys 使用以前的实现,请改用该值 "JournalHook"

若要将击键发送到相同的应用程序

调用 SendKeys.Send 类的 SendKeys.SendWaitSendKeys 方法。 指定的击键由应用程序的活动控件接收。

下面的代码示例使用 Send 模拟同时按下 Alt 键和 方向下键。 这些击键会导致 ComboBox 控件显示其下拉列表。 此示例假设有 FormButtonComboBox

private void button1_Click(object sender, EventArgs e)
{
    comboBox1.Focus();
    SendKeys.Send("%+{DOWN}");
}
Private Sub Button1_Click(sender As Object, e As EventArgs)
    ComboBox1.Focus()
    SendKeys.Send("%+{DOWN}")
End Sub

若要将击键发送到不同的应用程序

SendKeys.SendSendKeys.SendWait方法将击键发送到活动应用程序,通常是您正在发送击键的那个应用程序。 若要将击键发送到另一个应用程序,首先需要激活它。 由于没有用于激活另一个应用程序的托管方法,因此必须使用本机 Windows 方法来聚焦其他应用程序。 下面的代码示例使用平台调用来调用 FindWindowSetForegroundWindow 方法来激活计算器应用程序窗口,然后调用 Send 向计算器应用程序发出一系列计算。

下面的代码示例用于 Send 模拟在 Windows 计算器应用程序中按键的过程。 它首先搜索标题为 Calculator 的应用程序窗口,然后激活它。 激活后,将通过击键发送命令以计算 10 加 10。

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

private void button1_Click(object sender, EventArgs e)
{
    IntPtr calcWindow = FindWindow(null, "Calculator");

    if (SetForegroundWindow(calcWindow))
        SendKeys.Send("10{+}10=");
}
<Runtime.InteropServices.DllImport("USER32.DLL", CharSet:=Runtime.InteropServices.CharSet.Unicode)>
Public Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr : End Function

<Runtime.InteropServices.DllImport("USER32.DLL")>
Public Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean : End Function

Private Sub Button1_Click(sender As Object, e As EventArgs)
    Dim hCalcWindow As IntPtr = FindWindow(Nothing, "Calculator")

    If SetForegroundWindow(hCalcWindow) Then
        SendKeys.Send("10{+}10=")
    End If
End Sub

使用 OnEventName 方法

模拟键盘事件的最简单方法是对引发事件的对象调用方法。 大多数事件都有一个相应的触发方法,命名模式为 On,后接 EventName,例如 OnKeyPress。 此选项只能在自定义控件或窗体中使用,因为这些方法受到保护,并且不能从控件或窗体的上下文外部访问。

这些受保护的方法可用于模拟键盘事件。

  • OnKeyDown
  • OnKeyPress
  • OnKeyUp

有关这些事件的详细信息,请参阅 “使用键盘事件”。

另请参阅