คุณจำลอง Mouse Click ใน C # ได้อย่างไร?


128

คุณจำลองการคลิกเมาส์ในแอปพลิเคชัน C # winforms ได้อย่างไร


5
คุณอาจต้องการให้ข้อมูลเพิ่มเติมเพื่อให้ได้คำตอบที่เป็นประโยชน์
Andy

36
เคล็ดลับ: หากชื่อของคุณตรงกับคำถามของคุณแสดงว่าชื่อยาวเกินไปหรือคำถามสั้นเกินไป ในกรณีนี้เป็นอย่างหลังคุณต้องให้บริบทมากขึ้นเพื่อให้ทุกคนมีโอกาสที่เหมาะสมในการให้คำตอบที่เป็นประโยชน์กับคุณ
Guffa

คำตอบ:


145

ฉันได้รวมแหล่งข้อมูลหลายแหล่งเพื่อสร้างโค้ดด้านล่างซึ่งฉันกำลังใช้อยู่ ฉันได้ลบการอ้างอิง 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;
        }
    }
}

2
ฉันไม่เห็นข้อได้เปรียบของซอร์สโค้ดที่ยาวกว่าสิ่งที่โพสต์ Marcos Placona เมื่อ 17 เดือนที่แล้ว
Al Kepp

47
จากความคลุมเครือของคำถามฉันคิดว่าผู้คนอาจได้รับประโยชน์จากตัวอย่างที่ช่วยให้พวกเขาทำได้มากกว่าการคลิกซ้ายดูดคลิกขวาหรือกลางหรืออนุญาตให้คลิกและลาก
Keith

2
ใช้งานได้ดี ฉันมาที่นี่เพื่อหาของแบบนี้
CSharpie

นี่คือสิ่งที่ฉันกำลังค้นหา แต่คุณจะคลิกลงอย่างไรเลื่อนเมาส์ไปที่อื่นแล้วปล่อย ??
ninjaxelite

1
@ninjaxelite 1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp)ฉันเดาคุณส่ง อาจห่อด้วยวิธีผู้ช่วย
Michal Ciechan

137

ตัวอย่างที่ผมพบว่าอยู่ที่ไหนสักแห่ง ที่นี่ในอดีตที่ผ่านมา อาจช่วยได้บ้าง:

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
บางทีอาจจะอยู่ที่นี่ ?
mpen

3
เล่นดี. เพิ่มการอ้างอิงถึงคำตอบเดิม
Marcos Placona

2
ฉันได้รับข้อผิดพลาดเกี่ยวกับรหัสนี้: การเรียกใช้ฟังก์ชัน PInvoke 'MyForm! MyForm.Form1 :: mouse_event' ทำให้สแต็กไม่สมดุล อาจเป็นเพราะลายเซ็น PInvoke ที่มีการจัดการไม่ตรงกับลายเซ็นเป้าหมายที่ไม่มีการจัดการ ตรวจสอบว่ารูปแบบการเรียกและพารามิเตอร์ของลายเซ็น PInvoke ตรงกับลายเซ็นที่ไม่มีการจัดการเป้าหมาย ความคิดใด ๆ ?
Abdulla

12
คุณต้องส่ง X และ Y เป็น uints
Dibesjr

1
การทำงานอย่างสมบูรณ์ต้องมีการเปลี่ยนแปลงตำแหน่งเคอร์เซอร์ตามข้อกำหนด ...
Anurag Rabadia

14

การควบคุมบางอย่างเช่นปุ่มใน System.Windows.Forms มีเมธอด "PerformClick" เพื่อดำเนินการดังกล่าว


หากตัวควบคุมไม่มีเมธอด PerformClick คุณสามารถขยาย / เพิ่มได้เพียงแค่เรียก OnMouseClick ด้วยอาร์กิวเมนต์ MouseEventArgs ที่เหมาะสม
Tony Hopkinson

8

1
เป็นเรื่องแปลกที่สิ่งนี้ถูกแยกในเนมสเปซทดสอบ Visual Studio UI แต่ฉันจะใช้เวลานั้นมากกว่า PInvoke ทุกวันที่ฉันไม่จำเป็นต้องกรองเหตุการณ์ตามอุปกรณ์
kayleeFrye_onDeck

2
ดูเหมือนว่า Visual Studio Community edition จะไม่ได้มาพร้อมกับ DLL นี้
CM

2
ฉันใช้เวลาเพียงหนึ่งชั่วโมงในการพยายามทำให้สิ่งนี้ใช้งานได้โดยการคัดลอก DLL จากโครงการ "การทดสอบ UI ที่เข้ารหัส" ไปยังโครงการอื่นและเว้นแต่คุณจะใช้โครงการประเภท "การทดสอบ UI แบบเข้ารหัส" คำแนะนำของฉันคือ: ไม่ต้องกังวล แม้ว่าฉันจะคัดลอก DLL ทั้งหมดที่จำเป็น แต่ก็มีการโยน a InvalidUITestExtensionPackageExceptionออกไปดังนั้นดูเหมือนว่าจะยุ่งยากมากกับการทำงานในประเภทโครงการเฉพาะอย่างน่าเศร้า
Jez

@Jez - สะดวกที่จะทราบขอบคุณ ยังไม่เห็นปัญหาใด ๆ เลย แต่ตอนนี้อย่างน้อยฉันก็รู้ว่ามีอยู่บ้าง 0)
Rusty Nail

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 เพื่อทำการคลิกจริง
Ge Rong

0

พวกเขาเป็นความต้องการบางอย่างที่ฉันไม่สามารถมองเห็นสิ่งที่โดมเช่น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");
        }
    }
}

1
คุณยังสามารถทำ button1_Click (null, null) ได้หากคุณไม่ต้องการพารามิเตอร์เหล่านั้น
sab669

@ sab669 แน่นอน แต่ก็ยังขึ้นอยู่กับความต้องการของเขา :-)
WiiMaxx

คุณไม่ควรใช้nullในพารามิเตอร์ที่สองมันจะโยน a NullReferenceExceptionแทนใช้EventArgs.Empty
Etor Madiv

1
@EtorMadiv อย่างที่ฉันพูดไปก่อนหน้านี้มันขึ้นอยู่กับสิ่งที่คุณกำลังพยายามทำ ... เพราะถ้าคุณใช้มันเหมือนที่ฉันทำข้างต้นคุณจะไม่ได้รับNullReferenceException
WiiMaxx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.