How do you simulate Mouse Click in C#?
Asked Answered
S

7

155

How do you simulate Mouse clicks in C# winforms applications?

Sphygmic answered 10/3, 2010 at 12:17 Comment(2)
You might want to provide more information so that you can get a useful answer.Carpetbag
Tip: If your title is the same as your question, then the title is way too long or the question is way too short. In this case it's the latter, you have to give a lot more context for anyone to have a reasonable chance to give you a useful answer.Expedient
Y
194

I have combined several sources to produce the code below, which I am currently using. I have also removed the Windows.Forms references so I can use it from console and WPF applications without additional references.

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;
        }
    }
}
Yiyid answered 19/8, 2011 at 12:8 Comment(5)
I can't see any advantage of this long source code over what posted Marcos Placona 17 months ago.Fat
Given the vagueness of the question, I thought people might benefit from an example that allows them to do more than just a left click suck a right or middle click or allow click and drag.Yiyid
This is what I am searching, but how do you click down, move mouse somewhere else and then release??Machismo
@Machismo I am guessing you send 1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp). Potentially wrap it in a helper methodBackstage
@Yiyid - if I want to do a mouse click inside a TextBox on WinForm, how do I know what X and Y coordinates to use?Substructure
S
150

An example I found somewhere here in the past. Might be of some help:

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
}
Scrutiny answered 10/3, 2010 at 12:21 Comment(9)
Somewhere being here perhaps?Pancake
Well played. Added reference to the original answerScrutiny
I'm getting an error with this code: A call to PInvoke function 'MyForm!MyForm.Form1::mouse_event' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature. Any ideas?Motherwell
You need to cast the X and Y to uints.Unguentum
is this public static extern void mouse_event() a method/property of the solution project/app, in other words, I want solution and the app needs a mouse-click are two different apps. I'm building app to auto-detect and click on <OK> button of a msgbox from whoever other applications generate. 2-are X and Y the <OK> button positions?Loquitur
Works perfectly need some changes in cursor position as per requirements...Cioban
@MarcosPlacona - what is Cursor.Position.X and Cursor.Position.Y. Let us say I want to do a mouse click inside a TextBox, how do I know X and Y ?Substructure
X and Y should be int. With multiple monitors screen position can be negative. learn.microsoft.com/en-us/windows/win32/api/winuser/…Campanulate
X and Y should be int. With multiple monitors the position can have negative values.Campanulate
S
15

Some controls, like Button in System.Windows.Forms, have a "PerformClick" method to do just that.

Salmonoid answered 5/12, 2011 at 10:34 Comment(1)
If the control doesn't have a PerformClick method, you can extend/add one, just needs to call OnMouseClick with a suitable MouseEventArgs argument.Indaba
G
12
Mouse.Click();

Microsoft.VisualStudio.TestTools.UITesting

Gelsenkirchen answered 22/11, 2016 at 10:38 Comment(4)
It's kind of weird that this was isolated in the Visual Studio UI test namespace, but I'll take that over PInvoke any day that I don't need to filter events by-device.Converter
Looks like Visual Studio Community edition doesn't ship with this DLL.Agata
I just spent an hour trying to get this to work by copying DLLs over from a "coded UI test" project to another one and unless you're using a "coded UI test" project type, my advice is: don't bother. Even when I copied all the DLLs necessary it threw a InvalidUITestExtensionPackageException, so it seems to be extremely fussy about running in a particular project type, sadly.Crispin
@Crispin - Handy to know, thanks. Not seen any issues yet myself, but now I at least know some exist ;0)Gelsenkirchen
A
6

I have tried the code that Marcos posted and it didn't worked for me. Whatever i was given to the Y coordinate the cursor didn't moved on Y axis. The code below will work if you want the position of the cursor relative to the left-up corner of your desktop, not relative to your application.

    [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);
    }

I only use mouse_event function to actually perform the click. You can give X and Y what coordinates you want, i used values from textbox:

            X = Convert.ToInt32(tbX.Text);
            Y = Convert.ToInt32(tbY.Text);
Argyle answered 18/9, 2015 at 9:49 Comment(1)
this is the right one for me, basically Cursor.Position is good enough for positioning the mouse cursor to wherever you want, then use WIN32API to do the actual click.Barefoot
D
0

I use the InvokeOnClick() method. It takes two arguments: Control and EventArgs. If you need the EventArgs, then create an instance of it and pass it in, else use InvokeOnClick(controlToClick, null);. You can use a variety of Mouse event related arguments that derive from EventArgs such as MouseEventArgs.

Diapositive answered 2/9, 2020 at 20:0 Comment(0)
C
-1

they are some needs i can't see to dome thing like Keith or Marcos Placona did instead of just doing

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");
        }
    }
}
Comras answered 2/5, 2013 at 13:29 Comment(4)
You can also do button1_Click(null, null) if you don't need either of those parameters.Charleton
@Charleton sure but it still depends on his needs :-)Comras
you should not use null in the second parameter, it will throw a NullReferenceException, instead use EventArgs.EmptyJim
@EtorMadiv like i said before it depends on what you are trying todo ..., because if you use it like i did above you wont get a NullReferenceExceptionComras

© 2022 - 2024 — McMap. All rights reserved.