可以通过两个函数操作鼠标:
SetCursorPos使鼠标移动到指定位置;mouse_event使用MouseEventFlag枚举中的Move,也可以使鼠标移动。
mouse_event中使用不同的枚举值可以模拟不同的鼠标事件。
值得注意的是有几点:
1. 我们不能用mouse_event(MouseEventFlag.LeftDown, 10, 10, 0, UIntPtr.Zero);去模拟在(10, 10)处的左键事件,我们需要把这步拆成两步:
第一步:移动鼠标到(10,10)处,用SetCursorPos(10, 10);
第二步:触发左键,用mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
本质上是两步的事件,不能把window API 想的太聪明,认为它会自动跑到(10,10)处,再左键
2. MouseEventFlag的枚举值可以多个一起用,使用 | 操作符
鼠标左键按下和松开两个事件的组合即一次单击:
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 )
两次连续的鼠标左键单击事件 构成一次鼠标双击事件:
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 )
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 )
3. MouseEventFlag中有个Absolute枚举,如果没指定Absolute, 则mouse_event的操作是相对于上次鼠标所在的位置;如果指定了Absolute,则是相对于整个屏幕坐标的位置。
这里要注意,指定Absolute,鼠标的坐标会被约束在[0, 65535]之间。0即对应屏幕左,65535即对应屏幕右下角。
MSDN原话如下:
If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface, (65535,65535) maps onto the lower-right corner.
所以模拟在(10, 10)处的左键,代码应改为:
mouse_event(MOUSEEVENTF_LEFTDOWN, 10 * 65536 / Screen.PrimaryScreen.Bounds.Width, 10 * 65536 / Screen.PrimaryScreen.Bounds.Height, 0, 0);
如果显示器是一拖二的,想在第二个屏上使用mouse_event,就不能用Screen.PrimaryScreen了
.Net封装好的方法
int x = Control.MousePosition.X; int y = Control.MousePosition.Y;
GetWindowRect(new HandleRef(this, ptrStartBtn), out rect);
endPosition.X = (rect.left + rect.right) / 2;
endPosition.Y = (rect.top + rect.bottom) / 2;
SetCursorPos(endPosition.X, endPosition.Y);
mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
The section with shadow will help you set the cursor position to the application which you want, and then send a click event to it.