问题描述
我正在使用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。