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

是否可以捕获鼠标在另一个应用程序(如计算器)上单击的坐标,然后使用代码(C#)强制单击?,c#,winforms,winapi,mouse-hook,C#,Winforms,Winapi,Mouse Hook,我正在使用Windows窗体(C#)开发一个应用程序。我需要能够按下一个按钮,开始监控下一次鼠标点击在另一个应用程序中的位置。然后,需要使用此单击的坐标来强制稍后在同一应用程序中单击同一按钮。对于测试,我只是使用一个计算器,按下一个键来捕捉X和Y,然后按下另一个按钮再次按下该键,但它不起作用。如果能帮我找出我做错了什么,我们将不胜感激 我已经使用MouseKeyHook订阅了MouseKeyHook nuget install MouseKeyHook 您不能保证其他应用程序(计算器)响应您

我正在使用Windows窗体(C#)开发一个应用程序。我需要能够按下一个按钮,开始监控下一次鼠标点击在另一个应用程序中的位置。然后,需要使用此单击的坐标来强制稍后在同一应用程序中单击同一按钮。对于测试,我只是使用一个计算器,按下一个键来捕捉X和Y,然后按下另一个按钮再次按下该键,但它不起作用。如果能帮我找出我做错了什么,我们将不胜感激

我已经使用MouseKeyHook订阅了MouseKeyHook

 nuget install MouseKeyHook

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

此外,计算器是一个UWP窗口,您将使用
ChildWindowFromPointEx
获得一个空的
hWnd
。您应该使用来模拟鼠标输入,并确保单击的位置不被其他窗口覆盖。C#中的样本:


或者使用。

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

此外,计算器是一个UWP窗口,您将使用
ChildWindowFromPointEx
获得一个空的
hWnd
。您应该使用来模拟鼠标输入,并确保单击的位置不被其他窗口覆盖。C#中的样本:


或者使用。

您将
WM_LBUTTONDOWN
发送给所单击应用程序的顶级父级
HWND
,而不是发送给实际单击的任何特定子控件(如按钮)
WindowFromPoint()
不会给您一个子
HWND
,您需要
ChildWindowFromPoint()
。因此,您应该使用
SendInput()
而不是
PostMessage()
Hi@RemyLebeau感谢您抽出时间来研究这个问题。我尝试了你的建议,但仍然没有成功。有什么想法吗?您正在将
WM_LBUTTONDOWN
发送给所单击应用程序的顶级父级
HWND
,而不是发送给实际单击的任何特定子控件(如按钮)
WindowFromPoint()
不会给您一个子
HWND
,您需要
ChildWindowFromPoint()
。因此,您应该使用
SendInput()
而不是
PostMessage()
Hi@RemyLebeau感谢您抽出时间来研究这个问题。我尝试了你的建议,但仍然没有成功。有什么想法吗?
    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);
            
        }
   }
```.