同步模拟鼠标单击

时间:2014-07-15 13:03:45

标签: c# winapi mouse simulation

我尝试使用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;
        }
    }
}

0 个答案:

没有答案