c# - 你如何虚拟地执行鼠标移动和点击 [user32.dll]
问题描述
您如何虚拟执行鼠标移动和点击?
我的意思是,主鼠标不受影响,所以基本上“创建”第二个鼠标,通过设置 x/y 位置(首选 user32.dll)来控制。
我在这里读过一些类似的问题,但答案通常是用你的主鼠标,例如:
DllImport("user32")]
public static extern int SetCursorPos(int x, int y);
^ 这会将您的主鼠标移动到屏幕上的 x&y 位置,我想要的是使用“虚拟鼠标”执行此操作,这样我的主鼠标就不会移动,所以基本上我可以在这个“虚拟鼠标”执行时继续使用我的电脑例如,另一个窗口中的其他内容。
然后使用这个“虚拟鼠标”来执行点击[虚拟键码]
我试过这个:
IntPtr MakeLParam(int x, int y) => (IntPtr)((y << 16) | (x & 0xFFFF));
var pointPtr = MakeLParam(900, 1000);//x y cords
IntPtr hWnd = ScreenCapture.FindWindow(null, ScreenCapture.GetWindowName()); //Finds Window
PostMessage(hWnd, WM_MOUSEMOVE | WM_LBUTTONDOWN | WM_LBUTTONUP, IntPtr.Zero, pointPtr);
[DllImport("User32.dll")]
public static extern Int32 PostMessage(
IntPtr hWnd, // handle to destination window
int Msg, // message
IntPtr wParam, // first message parameter
IntPtr lParam); // second message parameter
但是什么都没有发生,我的猜测是 WM_MOUSEMOVE 无法正常工作
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int WM_COMMAND = 0x111;
public const int WM_LBUTTONDOWN = 0x201;
public const int WM_LBUTTONUP = 0x202;
public const int WM_LBUTTONDBLCLK = 0x203;
public const int WM_RBUTTONDOWN = 0x204;
public const int WM_RBUTTONUP = 0x205;
public const int WM_RBUTTONDBLCLK = 0x206;
public const int WM_MOUSEMOVE = 0x0200;
更新,我想我解决了一些问题!
在阅读了有关 PostMessage /SendInput 的更多信息后,我发现“应用程序窗口”可以有“应用程序窗口”的层,所以我使用 ispy++ 来检查它,是的,该程序还有另一个我想点击的层。
所以为了解决这个问题,我使用了我想点击的窗口的类名以及窗口名,下面是一个示例代码:
public static bool ClickTest()
{
IntPtr MakeLParam(int x, int y) => (IntPtr)((y << 16) | (x & 0xFFFF));//Just converts x&y to InPtr lParam
IntPtr WindowhWid = ScreenCapture.FindWindow(null, ScreenCapture.GetWindowName()); //Gets the window hWid
var ClasshWid = FindWindowEx(WindowhWid, IntPtr.Zero, "Classname", null); //Gets the Class hWid using WindowhWid AND the Class name (Need to find a way to get the classname using process list)
PostMessage(ClasshWid, WM_LBUTTONDOWN | WM_LBUTTONUP, 0, MakeLParam(938, 1011));//Finally sends it to the classhWid
return true;
}
使用这两个函数
[DllImport("User32.dll")]
public static extern int FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
string strClassName,
string strWindowName);
[DllImport("User32.dll")]
public static extern Int32 PostMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
IntPtr lParam); // second message parameter
请注意,如果应用程序窗口被最小化,它不会点击,但如果窗口在另一个应用程序窗口后面,它会点击!
X & Y 也是屏幕 X & Y 而不是应用程序 X & Y !
现在问题仍然存在,为什么在应用程序窗口最小化时它不起作用?
点击不会去任何地方,而是应用程序,所以在应用程序最小化时它不应该工作吗?
解决方案
它可能不是您需要做的事情和您所关心的事情,但AutoIT Dll以最简单的方式提供了大量随时可用的自动化功能。由于您依赖于 Windows DLL,因此它是完美的。
如果您仍然在自己的方式上 user32.dll 然后检查Low level hook,这就是我使用的。
不过,我强烈推荐 AutoIT dll,它可以为您节省大量时间来猜测无法正确响应的 windows 消息发生了什么
推荐阅读
- angularjs - 浏览器获取工作,但 AngularJS $http 服务有 CORS 错误
- r - docker 和 splashr 的 python 模块错误
- jenkins - Jenkins Pipeline Artifactory Promotion 用于多个存储库中的工件
- java - 提供静态内容时出错 Dropwziard
- javascript - 如何使用 JavaScript 触发 SVG 动画?(没有 jQuery)
- java - 从 java 运行带有参数的 Python 程序
- python - 检测正则表达式中的拉丁字符
- android - BottomNavigationView 不突出显示自定义图标
- google-sheets - #姓名?Google 表格数据透视表计算字段出错
- java - java - 如何使用来自不同数据类型的其他列表的值填充java中的列表?