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

问题描述

我正在使用Windows Form(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);
            
        }
   }
```.
 

解决方法

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

此外,计算器是一个UWP窗口,您将使用hWnd得到一个空的ChildWindowFromPointEx。您应该使用SendInput模拟鼠标输入,并确保单击的位置未被其他窗口覆盖。 C#中的示例:https://stackoverflow.com/a/54072028/10611792

或使用UI Automation