【问题标题】:How do you simulate Mouse Click in C#?如何在 C# 中模拟鼠标单击?
【发布时间】:2011-01-25 21:10:23
【问题描述】:

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

【问题讨论】:

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

标签: c# .net winforms


【解决方案1】:

我过去在 somewhere here 找到的一个例子。可能会有所帮助:

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
}

【讨论】:

  • 某处可能是here
  • 玩得很好。添加了对原始答案的参考
  • 我收到此代码错误:对 PInvoke 函数 'MyForm!MyForm.Form1::mouse_event' 的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。有什么想法吗?
  • 您需要将 X 和 Y 转换为 uint。
  • 作品完全需要根据要求对光标位置进行一些更改...
【解决方案2】:

我结合了几个来源来生成下面的代码,我目前正在使用它。我还删除了 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 相比,我看不出这段冗长的源代码有什么优势。
  • 考虑到问题的模糊性,我认为人们可能会受益于一个示例,该示例允许他们做的不仅仅是左键单击、右键或中键单击或允许单击并拖动。
  • 效果很好。我来这里是为了找这样的东西
  • 这是我正在搜索的,但是你如何点击向下,将鼠标移到其他地方然后释放??
  • @ninjaxelite 我猜你发送1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp)。可能将其包装在辅助方法中
【解决方案3】:

一些控件,比如 System.Windows.Forms 中的 Button,有一个“PerformClick”方法来做这件事。

【讨论】:

  • 如果控件没有PerformClick方法,您可以扩展/添加一个,只需要使用合适的MouseEventArgs参数调用OnMouseClick。
【解决方案4】:

他们是一些我看不到的需求,比如 KeithMarcos 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 当然,但这仍然取决于他的需要:-)
  • 你不应该在第二个参数中使用null,它会抛出一个NullReferenceException,而是使用EventArgs.Empty
  • @EtorMadiv 就像我之前说的,这取决于你要做什么......因为如果你像我上面那样使用它,你不会得到NullReferenceException
【解决方案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进行实际点击。
【解决方案6】:

【讨论】:

  • 在 Visual Studio UI 测试命名空间中隔离这有点奇怪,但我会在不需要按设备过滤事件的任何一天接管 PInvoke。
  • 看起来 Visual Studio 社区版不附带此 DLL。
  • 我花了一个小时试图通过将 DLL 从“编码的 UI 测试”项目复制到另一个项目来使其工作,除非您使用的是“编码的 UI 测试”项目类型,否则我的建议是:不要打扰。即使我复制了所有必要的 DLL,它也会抛出一个 InvalidUITestExtensionPackageException,所以很遗憾,在特定项目类型中运行似乎非常挑剔。
  • @Jez - 很方便知道,谢谢。我自己还没有看到任何问题,但现在我至少知道存在一些问题;0)
【解决方案7】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2014-01-03
    • 1970-01-01
    相关资源
    最近更新 更多