Come si simula il clic del mouse in C #?


128

Come simulate i clic del mouse nelle applicazioni winforms in C #?


5
Potresti voler fornire ulteriori informazioni in modo da poter ottenere una risposta utile.
Andy,

36
Suggerimento: se il titolo è uguale alla domanda, il titolo è troppo lungo o la domanda è troppo breve. In questo caso è quest'ultimo, devi dare molto più contesto a chiunque abbia una ragionevole possibilità di darti una risposta utile.
Guffa,

Risposte:


145

Ho combinato diverse fonti per produrre il codice seguente, che sto attualmente utilizzando. Ho anche rimosso i riferimenti Windows.Forms in modo da poterlo utilizzare dalla console e dalle applicazioni WPF senza riferimenti aggiuntivi.

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

2
Non vedo alcun vantaggio di questo lungo codice sorgente rispetto a quanto pubblicato Marcos Placona 17 mesi fa.
Al Kepp,

46
Data la vaghezza della domanda, ho pensato che le persone avrebbero potuto beneficiare di un esempio che consente loro di fare più di un semplice clic sinistro, succhiare un clic destro o centrale o consentire clic e trascinare.
Keith,

2
Funziona alla grande. Sono venuto qui alla ricerca di qualcosa del genere
CSharpie,

Questo è quello che sto cercando, ma come si fa a fare clic su, spostare il mouse da qualche altra parte e quindi rilasciare ??
ninjaxelite,

1
@ninjaxelite Suppongo tu invii 1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp).
Avvolgilo

137

Un esempio che ho trovato da qualche parte qui in passato. Potrebbe essere di qualche aiuto:

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
}

12
Forse da qualche parte qui ?
Aprire il

3
Ben fatto. Aggiunto riferimento alla risposta originale
Marcos Placona,

2
Ricevo un errore con questo codice: una chiamata alla funzione PInvoke "MyForm! MyForm.Form1 :: mouse_event" ha sbilanciato lo stack. Ciò è probabilmente dovuto al fatto che la firma gestita da PInvoke non corrisponde alla firma di destinazione non gestita. Verificare che la convenzione di chiamata e i parametri della firma PInvoke corrispondano alla firma non gestita di destinazione. Qualche idea?
Abdulla

12
Devi lanciare X e Y su uint.
Dibesjr,

1
Funziona perfettamente ha bisogno di alcuni cambiamenti nella posizione del cursore secondo i requisiti ...
Anurag Rabadia

14

Alcuni controlli, come Button in System.Windows.Forms, hanno un metodo "PerformClick" per fare proprio questo.


Se il controllo non ha un metodo PerformClick, è possibile estenderne / aggiungerne uno, è sufficiente chiamare OnMouseClick con un argomento MouseEventArgs adatto.
Tony Hopkinson,

8

1
È un po 'strano che questo sia stato isolato nello spazio dei nomi dei test dell'interfaccia utente di Visual Studio, ma lo prenderò su PInvoke ogni giorno che non ho bisogno di filtrare gli eventi per dispositivo.
kayleeFrye_onDeck

2
Sembra che Visual Studio Community Edition non venga fornito con questa DLL.
CM

2
Ho appena trascorso un'ora a cercare di farlo funzionare copiando le DLL da un progetto "test codificato dell'interfaccia utente" a un altro e, a meno che tu non stia usando un tipo di progetto "test codificato dell'interfaccia utente", il mio consiglio è: non preoccuparti. Anche quando ho copiato tutte le DLL necessarie è stato lanciato un InvalidUITestExtensionPackageException, quindi sembra essere estremamente esigente nell'esecuzione in un particolare tipo di progetto, purtroppo.
Jez,

@Jez - Pratico da sapere, grazie. Non ho ancora visto alcun problema, ma ora almeno so che ne esistono alcuni; 0)
Rusty Nail

5

Ho provato il codice pubblicato da Marcos e non ha funzionato per me. Qualunque cosa mi sia stata data alla coordinata Y, il cursore non si è mosso sull'asse Y. Il codice seguente funzionerà se si desidera la posizione del cursore rispetto all'angolo sinistro del desktop, non relativo all'applicazione.

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

Uso solo la funzione mouse_event per eseguire effettivamente il clic. Puoi dare a X e Y quali coordinate vuoi, ho usato i valori dalla casella di testo:

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

questo è quello giusto per me, sostanzialmente Cursor.Positionè abbastanza buono per posizionare il cursore del mouse dove vuoi, quindi usa WIN32API per fare il clic reale.
Ge Rong,

0

sono alcuni bisogni che non riesco a capire come hanno fatto Keith o Marcos Placona invece di farlo

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

1
Puoi anche fare button1_Click (null, null) se non hai bisogno di nessuno di questi parametri.
sab669,

@ sab669 certo ma dipende ancora dalle sue esigenze :-)
WiiMaxx il

non dovresti usare nullnel secondo parametro, lancerà un NullReferenceException, invece usaEventArgs.Empty
Etor Madiv il

1
@EtorMadiv come ho detto prima dipende da cosa stai cercando di fare ..., perché se lo usi come ho fatto sopra non otterrai unNullReferenceException
WiiMaxx
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.