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
17 개월 전에 Marcos Placona에 게시 한 것보다이 긴 소스 코드의 이점을 볼 수 없습니다.
Al Kepp

46
질문의 모호함을 감안할 때 사람들은 왼쪽 클릭보다 오른쪽 또는 중간 클릭을 빨거나 클릭 앤 드래그를 허용하는 것보다 더 많은 것을 할 수있는 예에서 이점을 얻을 수 있다고 생각했습니다.
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 서명의 호출 규칙 및 매개 변수가 대상 관리되지 않는 서명과 일치하는지 확인하십시오. 어떤 아이디어?
압둘라

12
X와 Y를 uint로 캐스트해야합니다.
Dibesjr

1
요구 사항에 따라 커서 위치의 변화가 완벽하게 필요합니다 ...
Anurag Rabadia

14

System.Windows.Forms의 Button과 같은 일부 컨트롤에는 "PerformClick"메서드가 있습니다.


컨트롤에 PerformClick 메서드가 없으면 확장 / 추가 할 수 있으며 적절한 MouseEventArgs 인수를 사용하여 OnMouseClick을 호출하면됩니다.
Tony Hopkinson

8

1
이것이 Visual Studio UI 테스트 네임 스페이스에서 분리 된 것은 이상하지만, 장치별로 이벤트를 필터링 할 필요가없는 PInvoke를 언젠가는 취할 것입니다.
kayleeFrye_onDeck

2
Visual Studio Community Edition은이 DLL과 함께 제공되지 않는 것 같습니다.
CM

2
"코드화 된 UI 테스트"프로젝트에서 다른 프로젝트로 DLL을 복사하여이 코드를 작동 시키려고 한 시간을 보냈습니다. "코드화 된 UI 테스트"프로젝트 유형을 사용하지 않는 한 제 충고는 다음과 같습니다. 필요한 모든 DLL을 복사해도을 던 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);
    }

실제로 click을 수행하기 위해 mouse_event 함수 만 사용합니다. X와 Y에 원하는 좌표를 줄 수 있습니다. 텍스트 상자의 값을 사용했습니다.

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

이것은 나에게 맞는 것입니다. 기본적으로 Cursor.Position마우스 커서를 원하는 위치에 배치하기에 충분합니다. 그런 다음 WIN32API를 사용하여 실제 클릭을하십시오.
Ge Rong

0

그들은 내가 좋아하는 돔 일에 볼 수있는 몇 가지 요구 사항입니다 키스마르코스 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두 번째 매개 변수 에는 사용하지 않아야 합니다 NullReferenceException. 대신에를 사용합니다.EventArgs.Empty
Etor Madiv

1
@EtorMadiv 내가 전에 말한 것처럼 당신이 할 일에 따라 달라집니다 ..., 당신이 내가 위에서했던 것처럼 그것을 사용하면NullReferenceException
WiiMaxx를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.