如何在C#中编程触发鼠标左键单击?

7
我该如何在程序中触发鼠标的左键点击事件?谢谢。
编辑:该事件不是直接在按钮上触发的。我瞄准的是Windows平台。

2
在哪个平台上?Winforms?WPF?Silverlight?Webforms(=HTML/JavaScript)?还是只是“Windows”(低级别)? - Marc Gravell
可能是如何在C#中模拟鼠标点击?的重复问题。 - Alex
3个回答

14

执行鼠标点击:

 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

        private const int MOUSEEVENTF_LEFTDOWN = 0x02;
        private const int MOUSEEVENTF_LEFTUP = 0x04;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        private const int MOUSEEVENTF_RIGHTUP = 0x10;

        public static void DoMouseClick()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }

要将光标移动到所需位置:

[DllImport("user32.dll")]
        static extern bool SetCursorPos(int X, int Y);

        public static void MoveCursorToPoint(int x, int y)
        {
            SetCursorPos(x, y);
        }

2
我看到这个,试过了,但是 mouse_event 函数已经过时了。现在我正在尝试使用 SendInput 来实现相同的功能。 - Alex
1
除了Andrei指出的mouse_event被SendInput取代之外,您还可以通过在第一个参数中设置MOUSEEVENTF_ABSOLUTE掩码并在第二个和第三个参数中传递x和y坐标来传递鼠标位置,而不是先调用SetCursorPos。 - rob
我将尝试使用这种方法,因为(如在sendinput答案中所评论的),SendInput对我来说还没有起作用。使用这种方法,我得到了一个错误:“Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Use.....\Debug\hprog.vshost.exe'。附加信息:调用PInvoke函数'prog1!prog1.FrmBlah::mouse_event'已经使堆栈不平衡。这可能是因为托管的PInvoke签名与非托管的目标签名不匹配。请检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。 - barlop

8
如果它在按钮上正确,您可以使用
button1.PerformClick();

否则,您可以查看此MSDN文章,其中讨论了模拟鼠标(和键盘)输入。
此外,此项目也可能有所帮助。在底层,它使用SendInput

对我来说,Java似乎比C#更好地支持在Windows上轻松点击鼠标的任意位置,但InputSimulator库正是我所寻找的。你应该在你的答案中更加突出它。 - rob

1

https://web.archive.org/web/20140214230712/http://www.pinvoke.net/default.aspx/user32.sendinput

使用Win32 API发送输入。

更新:

由于我不再使用Win32 API,因此当平台更改或网站不可用时,我将不会更新此答案以使其正确。由于此答案甚至不符合Stackoverflow标准(不包含答案本身,而是链接到一个外部的、现在已失效的资源),因此没有必要给它任何分数或花费更多时间。

相反,请查看Stackoverflow上的这个问题,我认为它是重复的:

如何在C#中模拟鼠标点击?


我发现这不起作用,例如Visual Studio调试器在UINTINPUT[]下面放了一条线。我发现没有名为UINT的类,但我可以将其更改为UInt32。但是我不知道如何相应更改INPUT[]以使其正常工作。 - barlop
@barlop 感谢您挖掘出这个宝藏 :) 我很抱歉无法帮助您。我已将其标记为废弃。寻找更好的答案,例如在这里 https://dev59.com/A3E95IYBdhLWcg3wMbB1 - Alex
你低估了你的答案的有效性。Andrei已经说过,mouse_event解决方案已经过时,而你的SendInput解决方案更加现代化。在你链接的问题中,最受欢迎的答案是mouse_event解决方案。因此,你的答案可能比那里的答案更加现代化。并且,仅仅因为一个好的网站pinvoke被劫持或重定向到redgate软件公司,并不意味着网页上的信息已经过时。事实上,pinvoke网站的主页目前显示正在维护中。 - barlop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接