我尝试使用mouse_event()
函数,但似乎它是异步工作的。
下面是我的代码(问题出在Main方法中)。 我设置了鼠标位置并模拟了点击,但是我的代码甚至在点击模拟发生之前就返回了上一个窗口(在最后一行)。
如何在不挂起线程100毫秒的情况下克服这种异步?
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace MouseSimulatingTesting
{
class Program
{
static void Main(string[] args)
{
Thread.Sleep(3000); //just for testing - to have time to have an ability to switch to another window
//remember current foreground window
IntPtr previousForegroundWindow = GetForegroundWindow();
IntPtr browserWindowHandle = GetBrowserWindow();
//set browser window to foreground to make a click in it
ForceActivateWindow(browserWindowHandle);
//make a click
SetCursorPos(150, 20);
mouse_event(LEFT_DOWN, 0, 0, 0, 0);
mouse_event(LEFT_UP, 0, 0, 0, 0);
//Thread.Sleep(100); //if I uncomment this line then everything works perfectly
//return previous foreground window to top
ForceActivateWindow(browserWindowHandle);
}
const int LEFT_DOWN = 0x00000002;
const int LEFT_UP = 0x00000004;
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
static public void ForceActivateWindow(IntPtr windowHandle)
{
uint processID;
uint foregroundThreadID = GetWindowThreadProcessId(GetForegroundWindow(), out processID);
uint mainThreadId = GetCurrentThreadId();
const uint SW_SHOW = 5;
if (foregroundThreadID != mainThreadId)
{
AttachThreadInput(foregroundThreadID, mainThreadId, true);
BringWindowToTop(windowHandle);
ShowWindow(windowHandle, SW_SHOW);
SetForegroundWindow(windowHandle);
AttachThreadInput(foregroundThreadID, mainThreadId, false);
}
else
{
BringWindowToTop(windowHandle);
ShowWindow(windowHandle, SW_SHOW);
SetForegroundWindow(windowHandle);
}
}
static IntPtr GetBrowserWindow()
{
var browserProcesses = Process.GetProcessesByName("opera");
if (browserProcesses.Length == 0)
throw new Exception("Browser is not opened");
return browserProcesses[0].MainWindowHandle;
}
}
}