在 Windows 窗体中模拟鼠标事件并不像模拟键盘事件那样简单。 Windows 窗体不提供帮助程序类来移动鼠标和调用鼠标单击操作。 控制鼠标的唯一选项是使用本机 Windows 方法。 如果使用的是自定义控件或窗体,则可以模拟鼠标事件,但不能直接控制鼠标。
事件
大多数事件都有一个相应的触发方法,命名模式为 On
,后接 EventName
,例如 OnMouseMove
。 此选项只能在自定义控件或窗体中使用,因为这些方法受到保护,并且不能从控件或窗体的上下文外部访问。 使用 OnMouseMove
等方法的缺点是它实际上无法控制鼠标或与控件交互,因此只会引发关联的事件。 例如,如果你想模拟将鼠标悬停在 ListBox 中的某一项上,则 OnMouseMove
和 ListBox
不会以光标下的突出显示的项的方式直观地作出反应。
这些受保护的方法可用于模拟鼠标事件。
OnMouseDown
OnMouseEnter
OnMouseHover
OnMouseLeave
OnMouseMove
OnMouseUp
OnMouseWheel
OnMouseClick
OnMouseDoubleClick
有关这些事件的详细信息,请参阅 使用鼠标事件
调用单击
考虑到大多数控件在单击时会执行某些操作,例如按钮调用用户代码或多选框更改选中状态,Windows 窗体提供了一种简单的方法来触发此类单击操作。 某些控件(如组合框)在单击时没有任何特殊反应,模拟单击对控件没有任何效果。
PerformClick
System.Windows.Forms.IButtonControl 接口提供模拟单击控件的 PerformClick 方法。 System.Windows.Forms.Button 和 System.Windows.Forms.LinkLabel 控件都实现此接口。
button1.PerformClick();
Button1.PerformClick()
InvokeClick
对于窗体的自定义控件,使用 InvokeOnClick 方法模拟鼠标单击。 这是一种受保护的方法,只能从窗体或派生的自定义控件中调用。
例如,以下代码从 button1
单击复选框。
private void button1_Click(object sender, EventArgs e)
{
InvokeOnClick(checkBox1, EventArgs.Empty);
}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
InvokeOnClick(CheckBox1, EventArgs.Empty)
End Sub
使用原生 Windows 方法
Windows 提供了可用于模拟鼠标移动和单击(如 User32.dll SendInput
和 User32.dll SetCursorPos
)的方法。 以下示例将鼠标光标移动到控件的中心:
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetCursorPos(int x, int y);
private void button1_Click(object sender, EventArgs e)
{
Point position = PointToScreen(checkBox1.Location) + new Size(checkBox1.Width / 2, checkBox1.Height / 2);
SetCursorPos(position.X, position.Y);
}
<Runtime.InteropServices.DllImport("USER32.DLL", EntryPoint:="SetCursorPos")>
Public Shared Function SetCursorPos(x As Integer, y As Integer) As Boolean : End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim position As Point = PointToScreen(CheckBox1.Location) + New Size(CheckBox1.Width / 2, CheckBox1.Height / 2)
SetCursorPos(position.X, position.Y)
End Sub