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