是否可以捕获鼠标在另一个应用程序(例如计算器)上单击的坐标,然后使用代码(C#)强制单击?

Is it possible to capture coordinates of mouse clicked on another application e.g calculator and later force a click using code (C#)?

我正在使用 Windows 表单 (C#) 开发应用程序。我需要能够按下一个按钮,该按钮开始监视另一个应用程序中下一次鼠标单击的位置。然后需要使用此点击的坐标来强制稍后在同一应用程序中点击同一按钮。为了进行测试,我只是使用计算器并按下一个键来捕获 X 和 Y,然后按下另一个按钮再次按下该键,但它不起作用。任何帮助找出我做错了什么的人将不胜感激。

我已经使用MouseKeyHook订阅了鼠标钩子

 nuget install MouseKeyHook
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern bool GetCursorPos(out Point lpPoint);

        [DllImport("user32.dll")]
        static extern IntPtr WindowFromPoint(System.Drawing.Point p);

        [DllImport("user32.dll")]
        static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
        [StructLayout(LayoutKind.Sequential)]
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

        const int WM_LBUTTONDOWN = 0x0201;

        private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

//Button click which starts the subscribe
        private void btnStart_Click(object sender, EventArgs e)
        {
            Subscribe();

        }

        private IKeyboardMouseEvents m_GlobalHook;
public void Subscribe()
        {
            // Note: for the application hook, use the Hook.AppEvents() instead
            m_GlobalHook = Hook.GlobalEvents();

            m_GlobalHook.MouseDownExt += GlobalHookMouseDownExt;
        }

        Point p;
        IntPtr hWnd;
        private void GlobalHookMouseDownExt(object sender, MouseEventExtArgs e)
        {

            if (GetCursorPos(out p))
            {
               IntPtr mainWindow = WindowFromPoint(p);
                hWnd = ChildWindowFromPointEx(mainWindow, p, 0x0000);

                RECT rct = new RECT();
                GetWindowRect(mainWindow, ref rct);
                X = p.X - rct.Left;
                Y = p.Y - rct.Top;
            }

            Unsubscribe();
        }

        public void Unsubscribe()
        {
            m_GlobalHook.MouseDownExt -= GlobalHookMouseDownExt;
            m_GlobalHook.Dispose();
        }


        
        private void btnClick_Click(object sender, EventArgs e)
        {
            PostMessage(hWnd, WM_LBUTTONDOWN,X, Y);
            
        }
   }
```.
 

您不能保证其他应用程序(计算器)会响应您发布的消息。

此外,计算器是一个UWPwindow,你会得到一个空的hWndChildWindowFromPointEx。你应该使用 SendInput to simulate mouse input and ensure that the clicked place is not covered by other windows. Sample in C#:

或使用UI Automation.