Làm thế nào để bạn mô phỏng Nhấp chuột trong C #?


128

Làm thế nào để bạn mô phỏng các lần nhấp chuột trong các ứng dụng winforms của C #?


5
Bạn có thể muốn cung cấp thêm thông tin để bạn có thể nhận được câu trả lời hữu ích.
Andy

36
Mẹo: Nếu tiêu đề của bạn giống với câu hỏi của bạn, thì tiêu đề quá dài hoặc câu hỏi quá ngắn. Trong trường hợp này là sau này, bạn phải cung cấp thêm nhiều bối cảnh cho bất kỳ ai để có cơ hội hợp lý để cung cấp cho bạn một câu trả lời hữu ích.
Guffa

Câu trả lời:


145

Tôi đã kết hợp một số nguồn để tạo mã dưới đây, hiện tôi đang sử dụng. Tôi cũng đã xóa các tham chiếu Windows.Forms để tôi có thể sử dụng nó từ các ứng dụng console và WPF mà không cần thêm tài liệu tham khảo.

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
Tôi không thể thấy bất kỳ lợi thế nào của mã nguồn dài này so với những gì được đăng Marcos Placona 17 tháng trước.
Al Kepp

46
Với sự mơ hồ của câu hỏi, tôi nghĩ mọi người có thể được hưởng lợi từ một ví dụ cho phép họ làm nhiều hơn là chỉ nhấp chuột trái hút một nhấp chuột phải hoặc giữa hoặc cho phép nhấp và kéo.
Keith

2
Công trình tuyệt vời. Tôi đến đây để tìm kiếm một cái gì đó như thế này
CSharpie

Đây là những gì tôi đang tìm kiếm, nhưng làm thế nào để bạn nhấp xuống, di chuyển chuột đến một nơi khác và sau đó phát hành ??
ninjaxelite

1
@ninjaxelite Tôi đoán bạn gửi 1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp). Có khả năng bọc nó trong một phương pháp trợ giúp
Michal Ciechan

137

Một ví dụ tôi thấy đâu đó ở đây trong quá khứ. Có thể là một số trợ giúp:

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
Ở đâu đó có lẽ ở đây ?
mở

3
Chơi tốt Đã thêm tham chiếu cho câu trả lời ban đầu
Marcos Placona

2
Tôi đang gặp lỗi với mã này: Cuộc gọi đến hàm PInvoke 'MyForm! MyForm.Form1 :: mouse_event' đã làm mất cân bằng ngăn xếp. Điều này có thể là do chữ ký PInvoke được quản lý không khớp với chữ ký đích không được quản lý. Kiểm tra xem quy ước gọi và tham số của chữ ký PInvoke có khớp với chữ ký không được quản lý đích không. Có ý kiến ​​gì không?
Abdulla

12
Bạn cần truyền X và Y cho các gợi ý.
Dibesjr

1
Hoạt động hoàn toàn cần một số thay đổi về vị trí con trỏ theo yêu cầu ...
Anurag Rabadia

14

Một số điều khiển, như Nút trong System.Windows.Forms, có phương thức "PerformanceClick" để làm việc đó.


Nếu điều khiển không có phương thức PerformanceClick, bạn có thể mở rộng / thêm một phương thức, chỉ cần gọi OnMouseClick bằng một đối số MouseEventArss phù hợp.
Tony Hopkinson

8

1
Thật kỳ lạ khi điều này bị cô lập trong không gian tên thử nghiệm UI của Visual Studio, nhưng tôi sẽ xử lý PInvoke bất kỳ ngày nào mà tôi không cần phải lọc các sự kiện theo thiết bị.
kayleeFrye_onDeck

2
Có vẻ như phiên bản Visual Studio Community không xuất xưởng với DLL này.
CM

2
Tôi chỉ mất một giờ cố gắng để làm việc này bằng cách sao chép DLL từ dự án "kiểm tra giao diện người dùng được mã hóa" sang dự án khác và trừ khi bạn đang sử dụng loại dự án "kiểm tra giao diện người dùng được mã hóa", lời khuyên của tôi là: đừng bận tâm. Ngay cả khi tôi sao chép tất cả các DLL cần thiết, nó đã ném một cái InvalidUITestExtensionPackageException, vì vậy nó dường như cực kỳ cầu kỳ về việc chạy trong một loại dự án cụ thể, thật đáng buồn.
Jez

@Jez - Tiện dụng để biết, cảm ơn. Bản thân tôi chưa thấy bất kỳ vấn đề nào, nhưng bây giờ tôi ít nhất biết một số tồn tại; 0)
Rusty Nail

5

Tôi đã thử mã mà Marcos đã đăng và nó không hoạt động với tôi. Bất cứ điều gì tôi được trao cho tọa độ Y, con trỏ không di chuyển trên trục Y. Mã bên dưới sẽ hoạt động nếu bạn muốn vị trí của con trỏ so với góc bên trái của màn hình nền, không liên quan đến ứng dụng của bạn.

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

Tôi chỉ sử dụng chức năng mouse_event để thực hiện nhấp chuột. Bạn có thể cung cấp cho X và Y tọa độ bạn muốn, tôi đã sử dụng các giá trị từ hộp văn bản:

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

Đây là một cái phù hợp với tôi, về cơ bản Cursor.Positionlà đủ tốt để định vị con trỏ chuột đến bất cứ nơi nào bạn muốn, sau đó sử dụng WIN32API để thực hiện nhấp chuột thực tế.
Ge Rong

0

chúng là một số nhu cầu mà tôi không thể thấy đối với những thứ như Keith hay Marcos Placona đã làm thay vì chỉ làm

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
Bạn cũng có thể thực hiện button1_Click (null, null) nếu bạn không cần một trong các tham số đó.
sab669

@ sab669 chắc chắn nhưng vẫn phụ thuộc vào nhu cầu của anh ấy :-)
WiiMaxx

bạn không nên sử dụng nulltrong tham số thứ hai, nó sẽ ném một NullReferenceException, thay vào đó sử dụngEventArgs.Empty
Etor Madiv 12/07/2016

1
@EtorMadiv như tôi đã nói trước khi nó phụ thuộc vào những gì bạn đang cố gắng làm ..., bởi vì nếu bạn sử dụng nó như tôi đã làm ở trên, bạn sẽ không nhận đượcNullReferenceException
WiiMaxx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.