如何在C#winforms应用程序中模拟鼠标单击?

评论

您可能需要提供更多信息,以便获得有用的答案。

提示:如果标题与问题相同,则标题太长或问题太短。在这种情况下,是后者,您必须给更多的背景信息,以便任何人都有合理的机会为您提供有用的答案。

#1 楼

我已经合并了多个源以产生下面的代码,这些代码我目前正在使用。我还删除了Windows.Forms引用,因此可以在控制台和WPF应用程序中使用它,而无需其他引用。

using System;
using System.Runtime.InteropServices;

public class MouseOperations
{
    [Flags]
    public enum MouseEventFlags
    {
        LeftDown = 0x00000002,
        LeftUp = 0x00000004,
        MiddleDown = 0x00000020,
        MiddleUp = 0x00000040,
        Move = 0x00000001,
        Absolute = 0x00008000,
        RightDown = 0x00000008,
        RightUp = 0x00000010
    }

    [DllImport("user32.dll", EntryPoint = "SetCursorPos")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetCursorPos(int x, int y);      

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetCursorPos(out MousePoint lpMousePoint);

    [DllImport("user32.dll")]
    private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

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

    public static void SetCursorPosition(MousePoint point)
    {
        SetCursorPos(point.X, point.Y);
    }

    public static MousePoint GetCursorPosition()
    {
        MousePoint currentMousePoint;
        var gotPoint = GetCursorPos(out currentMousePoint);
        if (!gotPoint) { currentMousePoint = new MousePoint(0, 0); }
        return currentMousePoint;
    }

    public static void MouseEvent(MouseEventFlags value)
    {
        MousePoint position = GetCursorPosition();

        mouse_event
            ((int)value,
             position.X,
             position.Y,
             0,
             0)
            ;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MousePoint
    {
        public int X;
        public int Y;

        public MousePoint(int x, int y)
        {
            X = x;
            Y = y;
        }
    }
}


评论


与17个月前发布的Marcos Placona相比,我看不出这种冗长的源代码有任何优势。

– Al Kepp
2011年8月19日在12:12

考虑到问题的模糊性,我认为人们可能会从一个示例中受益,该示例使他们不仅可以执行左键单击来吸引右键单击或中键单击,还可以单击并拖动。

–基思
2011年8月19日在15:01

效果很好。我来这里找这样的东西

– CSharpie
16年2月13日在7:08

这就是我要搜索的内容,但是如何单击鼠标,将鼠标移到其他位置然后释放?

– ninjaxelite
16/12/26在11:15

@ninjaxelite我猜您发送1. SetCursorPos,2. MouseEvent(LeftButtonDown),3. SetCursorPos,4. MouseEvent(LeftButtonUp)。可能将其包装在辅助方法中

– Michal Ciechan
18年4月30日在16:13

#2 楼

我过去在这里某处发现的一个例子。可能会有帮助:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class Form1 : Form
{
   [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
   public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
   //Mouse actions
   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 Form1()
   {
   }

   public void DoMouseClick()
   {
      //Call the imported function with the cursor's current position
      uint X = (uint)Cursor.Position.X;
      uint Y = (uint)Cursor.Position.Y;
      mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
   }

   //...other code needed for the application
}


评论


也许在这里某处?

– mpen
2012年1月29日23:25

打的好。添加了对原始答案的引用

– Marcos Placona
2012年3月27日16:09

我收到此代码错误:对PInvoke函数'MyForm!MyForm.Form1 :: mouse_event'的调用使堆栈不平衡。这可能是因为托管的PInvoke签名与非托管的目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。有任何想法吗?

–阿卜杜拉
2012年6月8日在22:53



您需要将X和Y强制转换为uint。

– Dibesjr
2013年1月5日19:10

完美地工作需要根据要求对光标位置进行一些更改...

–阿努拉格(Anurag Rabadia)
19年4月30日在12:36

#3 楼

某些控件(例如System.Windows.Forms中的Button)具有“ PerformClick”方法来执行此操作。

评论


如果控件没有PerformClick方法,则可以扩展/添加方法,只需使用合适的MouseEventArgs参数调用OnMouseClick。

–托尼·霍普金森
18年4月12日在22:46

#4 楼

Mouse.Click();


Microsoft.VisualStudio.TestTools.UITesting

评论


奇怪的是,这是在Visual Studio UI测试名称空间中隔离的,但是我不需要任何按设备筛选事件的任何一天,都将其视为PInvoke。

–kayleeFrye_onDeck
18年5月19日在5:51

看起来Visual Studio Community版没有附带此DLL。

– C.M.
18年8月30日在23:07

我只花了一个小时就尝试通过将DLL从“编码的UI测试”项目复制到另一个项目来使其正常工作,除非您使用的是“编码的UI测试”项目类型,否则我的建议是:不要打扰。即使当我复制了所有必需的DLL时,它也会引发InvalidUITestExtensionPackageException,因此可悲的是,在特定项目类型中运行似乎非常挑剔。

–杰兹
18-10-20在9:31

@Jez-方便知道,谢谢。我本人尚未见任何问题,但现在我至少知道一些问题; 0)

–生锈的指甲
18-10-22在1:05

#5 楼

我已经尝试了Marcos发布的代码,但对我没有用。无论给我什么Y坐标,光标都不会在Y轴上移动。如果您希望光标相对于桌面的左上角而不是相对于应用程序,则下面的代码将起作用。

    [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_MOVE = 0x0001;

    public void DoMouseClick()
    {
        X = Cursor.Position.X;
        Y = Cursor.Position.Y;

        //move to coordinates
        pt = (Point)pc.ConvertFromString(X + "," + Y);
        Cursor.Position = pt;       

        //perform click            
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    }


我只使用mouse_event函数实际执行单击。
您可以给X和Y所需的坐标,我使用了文本框中的值:

            X = Convert.ToInt32(tbX.Text);
            Y = Convert.ToInt32(tbY.Text);


评论


这对我来说是正确的,基本上是Cursor.Position足以将鼠标光标定位到您想要的任何位置,然后使用WIN32API进行实际单击。

–葛蓉
17-09-20在8:32



#6 楼

它们是我看不到像Keith或Marcos Placona这样的东西而不是仅仅做的一些需求

using System;
using System.Windows.Forms;

namespace WFsimulateMouseClick
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            button1_Click(button1, new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, 1, 1, 1));

            //by the way
            //button1.PerformClick();
            // and
            //button1_Click(button1, new EventArgs());
            // are the same
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("clicked");
        }
    }
}


评论


如果不需要这些参数中的任何一个,也可以执行button1_Click(null,null)。

–sab669
13-10-15在15:43



@ sab669当然可以,但这仍然取决于他的需求:-)

– WiiMaxx
13-10-17在7:58

您不应该在第二个参数中使用null,它会抛出NullReferenceException,而是使用EventArgs.Empty

– Etor Madiv
16年7月12日在19:46

就像我之前所说的@EtorMadiv取决于您要执行的操作...,因为如果您像我上面那样使用它,则不会得到NullReferenceException

– WiiMaxx
16年7月12日在22:37

#7 楼

我使用InvokeOnClick()方法。它带有两个参数:Control和EventArgs。如果需要EventArgs,则创建它的一个实例并将其传递,否则使用InvokeOnClick(controlToClick, null);。您可以使用从EventArgs派生的各种与Mouse事件相关的参数,例如MouseEventArgs。