NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# 2부 - 누구나 쉽게 할 수 있는 C# 매크로 만들기. (마우스 클릭하기.)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 비개발자분들을 대상으로 작성하는 글이라서 아주~ 세세한 부분까지 다 스샷을 떠가면서 도움말을 작성하고 있습니다. 따라서, 개발자분들이 이 글을 보시면 상당히 답답할 수 있는데요. 사실 개발자라면... 굳이 이글을 안보더라도 매크로쯤은 뚝딱! 만들어 낼겁니다. 매크로 만들기 예제들은 인터넷에 널리고 널렸으니까요^^; 이전 1부 내용을 아직 안보신 분들은 [ 여기 ]를 클릭해서 개발 환경을 먼저 갖추고 이 글을 보셔야 합니다~ 비주얼 스튜디오를 실행하고, MyPlayer 프로젝트를 불러옵니다.

    9aRGw50.png

     

     

    매크로를 실행하고, 중지할 수 있는 버튼을 만드는것부터 시작해야 합니다. 아래 동영상을 참고해서 버튼 2개를 추가하고, 각각 표시할 텍스트를 수정 해주세요.

    A15tBpl.gif

     

     

    각각의 버튼을 더블 클릭하면 버튼을 눌렀을 때 동작해야 하는 이벤트 처리기를 자동으로 추가 해줍니다.

    nnwXrWt.gif

     

     

    C#에는 윈도우에 마우스 이벤트를 줄 수 있는 기능이 없습니다. 그래서, 윈도우 API인 win32 라이브러리를 이용해야 합니다. 다행스럽게도~ C나 C++처럼 윈도우 라이브러리를 쉽게 가져와서 사용할 수 있습니다. 이제 마우스 클릭에 대한 코드를 작성 해볼까요? 아래 2줄을 추가하세요.

            const uint LBUTTONDOWN = 0x0002;    // 왼쪽 마우스 버튼 누름
            const uint LBUTTONUP = 0x0004;      // 왼쪽 마우스 버튼 땜

     

    전체 코드는 아래와 같습니다.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace MyPlayer
    {
        public partial class Form1 : Form
        {
            const uint LBUTTONDOWN = 0x0002;    // 왼쪽 마우스 버튼 누름
            const uint LBUTTONUP = 0x0004;      // 왼쪽 마우스 버튼 땜
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
    
            }
        }
    }

     

    주석(// ...)에도 설명을 달아두었지만, 마우스 클릭은 기본적으로 마우스를 누르고 때는 동작을 말합니다. 그렇기 때문에 LBUTTONDOWNLBUTTONUP으로 윈도우에 신호를 줘야 합니다. 신호 값은 0x00020x0004와 같은 16진수 값입니다. 이 값은 컴퓨터 언어로 우리가 외워서 사용하기는 쉽지 않습니다. 2개정도야 뭐 문제가 안되겠지만요^^; 매크로를 만들다보면 무수히 많은 비트 값을 처리해야 하는데요. 이런 값들을 사용하기 쉽게 하려고 이름을 지어준다고 생각하시면 이해하기 쉬울겁니다. 아래와 같이 win32 라이브러리를 추가 해줍니다.

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace MyPlayer
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll")]
            static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    
            const uint LBUTTONDOWN = 0x0002;    // 왼쪽 마우스 버튼 누름
            const uint LBUTTONUP = 0x0004;      // 왼쪽 마우스 버튼 땜

     

    그냥 알아보기 쉽게 숫자를 사용하면 될텐데 왜 16진수를 사용하는지 약간 궁금할수도 있습니다. 16진수는 0부터 F까지 16개의 수를 가집니다.

    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

     

    대부분의 프로그래밍 언어에서 숫자(Integer)는 2바이트로 이루어져 있습니다. 1바이트는 8비트로 이루어져 있죠. 그래서 숫자형은 16비트입니다. 8비트를 반으로 나누면 4비트가 되는데 4비트는 1부터 16까지 표현이 가능합니다. 이는 컴퓨터의 CPU가 한번에 처리할 수 있는 최소 단위와 동일해서 2진수와 변환이 쉬운 16진수를 사용하게 되었습니다. 그래서 16비트의 숫자형에는 0xFFFF까지 넣을 수 있습니다. 요즘은 32비트, 64비트를 한번에 처리할 수 있습니다. 초창기에 컴퓨터 처리 단위가 지금까지 이어져서 사용된다고 이해하면 되겠습니다^^; 홈페이지 어딘가에... CPU, Memory, 컴퓨터에 대해 작성해둔 글이 있는데 한번 찾아보시면 좋을거 같네요.

     

    위 코드에서 불필요한 using은 제거한 상태입니다. 일단, DllImport는 비관리 라이브러리에서 정적 메소드를 사용할 수 있도록 해주는 C# 특성(Attribute)입니다. 점점 어려운 용어들이 나오고 있어서... 설명해야 하나 말아야 하나 고민이 깊어집니다. 개발자라면 그냥 아는 이야기들인데요. 이걸 설명하려면 또 많은 시간을 잡아먹을듯 하군요. 여러분들은 단순히 비관리(C나 C++로 만들어진 동적 라이브러리) 기능을 가져다가 쓸 때 이 특성을 이용하면 된다고 이해하시면 됩니다. 바탕화면의 아이콘들의 좌표를 알아내기 위해 엔지엠 에디터를 실행하고, 마우스 액션을 하나 추가 해줍니다.

    [ 엔지엠 에디터 무료 버전 다운로드 받기 ]

    7iW9THm.gif

     

     

    우측 속성창에서 마우스 좌표 속성을 선택하세요. 그러면, 우측에 "..." 버튼이 표시됩니다.

    xUHplgG.png

     

     

    "..." 버튼을 클릭한 후 바탕화면의 "내 PC" 로 이동하세요. 그리고, F1을 누르면 해당 좌표를 확인할 수 있습니다. 제 모니터 해상도(1920x1080) 기준 "내 PC"의 좌표는 "40, 31"입니다. 이 값을 아래와 같이 마우스 클릭 좌표로 사용하면 됩니다. 완성된 전체 코드입니다.

    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace MyPlayer
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll")]
            static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    
            const uint LBUTTONDOWN = 0x0002;    // 왼쪽 마우스 버튼 누름
            const uint LBUTTONUP = 0x0004;      // 왼쪽 마우스 버튼 땜
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                Cursor.Position = new Point(40, 31); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
    
            }
        }
    }
    

     

    간단하죠? 이제 정상적으로 동작하는지 테스트를 해볼까요? 비주얼 스튜디오에서 F5(실행)를 누르거나 아래 동영상처럼 ▶ 버튼을 클릭해도 됩니다. 우리가 만든 프로그램이 컴파일된 후 아래와 같은 프로그램이 실행됩니다. 여기서 실행 버튼을 클릭하면 정확하게 내 PC를 클릭합니다.

    0LO58M4.gif

     

     

    순차적으로 바탕화면의 모든 아이콘을 클릭 해볼까요? 엔지엠 에디터에서 마우스 클릭 액션의 "..."을 눌러서 각각의 좌표를 알아냅니다. 그리고, 아래와 같이 코드를 3번 복사한 후 좌표 값만 변경 해줍니다. 이 때 X 좌표는 동일하므로 Y 좌표만 변경해주면 됩니다.

    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace MyPlayer
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll")]
            static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    
            const uint LBUTTONDOWN = 0x0002;    // 왼쪽 마우스 버튼 누름
            const uint LBUTTONUP = 0x0004;      // 왼쪽 마우스 버튼 땜
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                Cursor.Position = new Point(40, 31); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                Cursor.Position = new Point(40, 109); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                Cursor.Position = new Point(40, 195); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                Cursor.Position = new Point(40, 278); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
    
            }
        }
    }
    

     

     

    다시 실행 해보면, 아래 동영상처럼 동작 할겁니다. 그런데 마우스가 순차적으로 클릭한건지 잘 확인이 되지 않습니다. 너무 빠르기 때문인데요. 코드를 약간 수정해야 할듯 합니다.

    kO2v0iA.gif

     

     

    마우스 클릭 사이에 System.Threading.Thread.Sleep(500); 을 추가해줬습니다. 이 코드는 0.5초(500) 쉰다는 뜻입니다.

            private void button1_Click(object sender, EventArgs e)
            {
                Cursor.Position = new Point(40, 31); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                System.Threading.Thread.Sleep(500);
    
                Cursor.Position = new Point(40, 109); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                System.Threading.Thread.Sleep(500);
    
                Cursor.Position = new Point(40, 195); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                System.Threading.Thread.Sleep(500);
    
                Cursor.Position = new Point(40, 278); // 내 PC 좌표
                mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                mouse_event(LBUTTONUP, 0, 0, 0, 0);
            }

     

     

    수정된 코드를 확인 해볼까요? 여러분들도 아래 동영상처럼 0.5초 간격으로 바탕화면의 아이콘을 클릭할겁니다.

    HMPaAL3.gif

     

     

    추가로, 이 동작을 5번 반복하려면 어떻게 해야 할까요? for문으로 감싼 후 조건을 5로 주면 됩니다. C# 반복문에 대한 자세한 설명은 [ 여기 ]를 참고하세요.

            private void button1_Click(object sender, EventArgs e)
            {
                for (int i = 0; i < 5; i++)
                {
                    Cursor.Position = new Point(40, 31); // 내 PC 좌표
                    mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                    mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                    System.Threading.Thread.Sleep(500);
    
                    Cursor.Position = new Point(40, 109); // 내 PC 좌표
                    mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                    mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                    System.Threading.Thread.Sleep(500);
    
                    Cursor.Position = new Point(40, 195); // 내 PC 좌표
                    mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                    mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                    System.Threading.Thread.Sleep(500);
    
                    Cursor.Position = new Point(40, 278); // 내 PC 좌표
                    mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                    mouse_event(LBUTTONUP, 0, 0, 0, 0);
                }
            }

     

     

    5번 반복하고 매크로가 중지 되었습니다.

    jLajfFF.gif

     

     

    마지막으로 중지 버튼을 누르면 매크로의 동작이 남아 있더라도 즉시 중지되도록 만들어보겠습니다. 마우스의 제어권을 사용자가 아닌 매크로가 가지고 있으므로, 중지 버튼을 누를 시간이 필요합니다. 그래서, "System.Threading.Thread.Sleep(500);" 값을 "System.Threading.Thread.Sleep(1000);" 으로 변경 했습니다. 사용자가 중지 버튼을 눌렀는지 확인하기 위한 상태 저장용 변수를 하나 추가 해줍니다.

    bool isStop = true;

     

    시작 버튼을 누르면 싱행중이니 이 값은 false로 바뀌고, 중지 버튼을 누르면 이 값은 true로 변경됩니다. 전체 코드는 아래와 같습니다.

    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace MyPlayer
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll")]
            static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    
            const uint LBUTTONDOWN = 0x0002;    // 왼쪽 마우스 버튼 누름
            const uint LBUTTONUP = 0x0004;      // 왼쪽 마우스 버튼 땜
    
            bool isStop = true;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                isStop = false;
    
                new System.Threading.Thread(new System.Threading.ThreadStart(delegate
                {
                    for (int i = 0; i < 5; i++)
                    {
                        Cursor.Position = new Point(40, 31); // 내 PC 좌표
                        mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                        mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                        if (isStop) break;
                        System.Threading.Thread.Sleep(1000);
    
                        Cursor.Position = new Point(40, 109); // 내 PC 좌표
                        mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                        mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                        if (isStop) break;
                        System.Threading.Thread.Sleep(1000);
    
                        Cursor.Position = new Point(40, 195); // 내 PC 좌표
                        mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                        mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                        if (isStop) break;
                        System.Threading.Thread.Sleep(1000);
    
                        Cursor.Position = new Point(40, 278); // 내 PC 좌표
                        mouse_event(LBUTTONDOWN, 0, 0, 0, 0);
                        mouse_event(LBUTTONUP, 0, 0, 0, 0);
    
                        if (isStop) break;
                        System.Threading.Thread.Sleep(1000);
                    }
                })).Start();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                isStop = true;
            }
        }
    }
    

     

     

    실행중에 재빠르게 중지 버튼을 눌러보세요. 5회 반복하지 않고 매크로가 중지됩니다.

    ZwznByb.gif

     

     

    이렇게해서 간단하게 마우스 매크로를 만들어 봤습니다. 사실, 여러가지 많은 테스트를 해보고 싶지만~ 가급적이면 C# 언어 강좌를 보고 직접 학습하면서 살을 붙여 나가는게 좋습니다. 어느정도 기초 지식과 응용력이 있어야 더 좋은 매크로를 만들 수 있거든요. 단순히 마우스 클릭만으로 이루어진 간단한 업무의 경우 이정도만 알아도 좌표를 가져다가 클릭으로 처리할 수 있기도 합니다. 복잡한 업무의 경우에는 더 좋은 도구를 사용하거나 더 많은 개발 지식이 필요하겠지만요^^;

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.