我遇到了从后台线程自动点击鼠标的问题。
目前,我有一个后台主题,它不断收集在特定窗口中点击的点列表。
当点击这些点时,我会调用一种方法来点击这些点。一旦我尝试从该后台线程迭代列表,它就会重新启动后台方法。
我已经实现了一个委托,以便在主线程上运行click方法。这允许我迭代列表。当我调试/断点点击它应该按其命中的位置的方法。虽然当我没有断点时,似乎无法运行该方法。我已将延迟置于ClickOnPoint
以上以显示鼠标移动但鼠标位置不会改变。
非常感谢任何帮助。
我是否正确使用代表?我应该在表格上还是在其他地方拨打InvokeRequired
?
代表定义:
delegate void ClickPositionsCallback(IntPtr handle, int position, Dictionary<int,Rectangle> positions);
从后台线程调用:
this.ClickPositions(kvp.Key, position.Key, positions);
检查是否需要调用的方法
private void ClickPositions(IntPtr handle,int position,Dictionary<int,Rectangle> positions)
{
if (this.InvokeRequired)
{
ClickPositionsCallback = new ClickPositionsCallback(ClickPositions);
this.Invoke(d, new object[] { handle,position,positions });
}
else
{
this.clickPositions(handle, position, positions);
}
}
迭代列表并执行点击的方法:
private void clickPositions(IntPtr intPtr, int position,Dictionary<int, Rectangle> positions )
{
SetForegroundWindow(intPtr);
List<Point> Points = new List<Point>();
lock (positions)
{
for (int i = 0; i < positions.Count; i++)
{
Points.Add(new Point(positions[((position + i) % 6)+1].Left + positions[((position + i )% 6) + 1].Width / 2, positions[((position + i) % 6) + 1].Top + positions[((position + i) % 6) + 1].Height / 2));
}
}
var oldPos = Cursor.Position;
foreach (Point p in Points)
{
ClickOnPoint(intPtr, p);
}
Cursor.Position = oldPos;
}
ClickOnPoint方法
private void ClickOnPoint(IntPtr wndHandle, Point clientPoint)
{
/// get screen coordinates
ClientToScreen(wndHandle, ref clientPoint);
/// set cursor on coords, and press mouse
Cursor.Position = new Point(clientPoint.X, clientPoint.Y - SystemInformation.CaptionHeight);
mouse_event(0x00000002, 0, 0, 0, UIntPtr.Zero); // left mouse button down
mouse_event(0x00000004, 0, 0, 0, UIntPtr.Zero); // left mouse button up
}