본문 바로가기
이미지 매크로

C# .NET 매크로 프로그램 만들기. (마우스 후킹 이벤트 1부)

by 업무자동화 2024. 5. 12.
반응형

유료 매크로 프로그램 다운로드

http://ngmsoftware.com/bbs/board.php?bo_table=product_review 

 

엔지엠소프트웨어

엔지엠 매크로는 복잡한 반복작업을 자동화할 수 있습니다. PC 게임, 모바일 게임을 최적으로 지원하며 모든 PC 프로그램 및 업무에 적용할 수 있습니다.

www.ngmsoftware.com

#매크로 #메크로 #매크로프로그램 #엔지엠소프트웨어 #엔지엠에디터 #엔지엠플레이어 #비활성매크로 #하드웨어매크로 #기계식매크로 #마우스광클릭 #키보드매크로 #이미지서치 #이미지매치 #블로그 #카페 #인스타그램 #유튜브 #소셜네트워크 #카카오톡 #텔레그램 #자동화

 

 

  • 엔지엠 커뮤니티 월 이용료: 4,500원, 1년 이용료: 55,000원 (전체 기능의 80프로)
  • 엔지엠 얼티밋 월 이용료: 6,500원, 1년 이용료: 77,000원 (전체 기능의 90프로)
  • 엔지엠 엔터프라이즈 월 이용료: 9,200원, 1년 이용료: 110,000원 (전체 기능 사용)

 

안녕하세요. 엔지엠소프트웨어입니다. 오늘은 마우스 후킹에 대해서 알아보겠습니다. 엔지엠 매크로 6에는 마우스 다운과 마우스 업 이벤트가 존재하는데요. 엔지엠 매크로 7은 여기에서 더 확장된 다양한 기능들을 제공할 수 있도록 할거예요. 그래서, 몇몇 추가된 부분들이 있고 기존의 윈도우 후킹 방식과 다르게 이벤트 핸들러를 디바이스에 연결해서 신호를 받도록 변경했습니다.

 

엠지엠 매크로를 새롭게 다시 만들면서 이벤트에 관련된 액션은 필요가 없을줄 알았습니다. 그래서, 가능하면 비동기로 처리할 수 있는 그룹 액션을 사용하려고 했습니다. 그런데, 외부에서 받아와야 하는 이벤트는 비동기로 순간적인 신호를 캐치할 방법이 없더라고요. 이런 시나리오가 생각보다 많아서 비동기 그룹 액션의 한계 때문에 이벤트 핸들러를 할당할 수 있는 새로운 로직이 필요하게 되었습니다. 이벤트 액션은 사용하지 않을줄 알았는데 어쩔 수 없이 기존 이벤트 로직과 유사하게 만들어야 할거 같네요.

 

이벤트는 마우스와 키보드 2개를 미리 추가해두었습니다.

 

 

카테고리만 다를뿐 클래스 이름은 동일합니다. 프로젝트의 논리 구조를 따라서 네임스페이스가 만들어지기 때문에 이름이 같아도 문제 없습니다.

 

 

글로벌 인터페이스가 하나 필요하게 되었습니다. 이벤트 핸들러를 일단 연결하면 어느 시점에 해제할 수 있어야 하고, 매크로가 중지 또는 완료될 때 할당된 이벤트 핸들러들을 전부 제거해줘야 합니다. 이벤트는 구조적으로 구독이기 때문에 여러개의 구독이 포함될 수 있습니다. 보통, 델리게이트(델리깃, Delegate: 대리자)를 이미 구현하고 있는 핸들러를 기본 사용합니다.

namespace Ai.Interface
{
    public interface IEvent : IDisposable
    {
        string? ID { get; }

        string? EventID { get; }
    }
}

 

IEvent 인터페이스는 이벤트를 식별할 수 있는 아이디가 필수로 제공되어야 하고, 이벤트가 발생했을 때 이동할 EventID도 존재해야 합니다. 그리고, IDisposable을 구현해야 합니다. 대부분의 이벤트 핸들러는 사용자가 명시적으로 메모리에서 해제할 수 있도록 해야 합니다. 이벤트의 경우 추가 연산자와 삭제 연산자를 이용합니다.

 

인터페이스를 구현하는 코드입니다.

[LocalizedCategory("Action")]
[LocalizedDisplayName("GotoID")]
[LocalizedDescription("GotoID")]
[Browsable(true)]
[DefaultValue(null)]
[TypeConverter(typeof(TypeConverter.ActionIdConverter))]
public string? EventID { get; set; }

[LocalizedCategory("Action")]
[LocalizedDisplayName("MouseState")]
[LocalizedDescription("MouseState")]
[Browsable(true)]
[DefaultValue(null)]
public Ai.Definition.MouseState[]? MouseState { get; set; }

 

마우스 이벤트를 감지하기 위한 옵션은 아래와 같습니다.

public enum MouseState
{
    Unknown = 0,
    LeftDown = 1,
    LeftUp = 2,
    LeftClick = 3,
    RightDown = 4,
    RightUp = 5,
    RightClick = 6,
    MiddleDown = 7,
    MiddleUp = 8,
    MiddleClick = 9,
    X1Down = 10,
    X1Up = 11,
    X1Click = 12,
    X2Down = 13,
    X2Up = 14,
    X2Click = 15,
    Move = 16,
    Wheel = 17
}

 

기존 엔지엠 6 버전은 마우스 다운과 업만 존재했는데요. 새로운 버전에서는 더 다양한 옵션을 제공합니다. 그리고, 여러개를 같이 체크할 수 있습니다.

 

매크로를 실행했을 때 효율을 위해서 사용자가 선택한 그룹에 속한 이벤트 핸들러만 연결하도록 했습니다. 

public override string? Execute(Ai.Interface.IPlayer player)
{
    _player = player;
    player.Events.Add(this);

    if (_mouseHook == null)
        _mouseHook = new MouseHookerHandler();

    if (MouseState.Contains(Definition.MouseState.LeftDown) || MouseState.Contains(Definition.MouseState.RightDown) || MouseState.Contains(Definition.MouseState.MiddleDown))
        _mouseHook.MousePressed += Hook_MousePressed;

    if (MouseState.Contains(Definition.MouseState.LeftUp) || MouseState.Contains(Definition.MouseState.RightUp) || MouseState.Contains(Definition.MouseState.MiddleUp))
        _mouseHook.MouseReleased += _mouseHook_MouseReleased;

    if (MouseState.Contains(Definition.MouseState.LeftClick) || MouseState.Contains(Definition.MouseState.RightClick) || MouseState.Contains(Definition.MouseState.MiddleClick))
        _mouseHook.MouseClicked += _mouseHook_MouseClicked;

    if (MouseState.Contains(Definition.MouseState.Move))
        _mouseHook.MouseMoved += _mouseHook_MouseMoved;

    if (MouseState.Contains(Definition.MouseState.Wheel))
        _mouseHook.MouseWheel += _mouseHook_MouseWheel;

    return null;
}

 

이벤트가 발생하면 처리하는 로직을 만들어야 하는데요. 대부분의 코드가 동일합니다.

private void Hook_MousePressed(object? sender, MouseHookEventArgs e)
{
    if (SuppressEvent)
        e.SuppressEvent = true;

    switch (e.Data.Button)
    {
        case SharpHook.Native.MouseButton.Button1:
            if (MouseState.Contains(Definition.MouseState.LeftDown))
                _player.SetForceGotoId(EventID);
            break;
        case SharpHook.Native.MouseButton.Button2:
            if (MouseState.Contains(Definition.MouseState.RightDown))
                _player.SetForceGotoId(EventID);
            break;
        case SharpHook.Native.MouseButton.Button3:
            if (MouseState.Contains(Definition.MouseState.MiddleDown))
                _player.SetForceGotoId(EventID);
            break;
        case SharpHook.Native.MouseButton.Button4:
            if (MouseState.Contains(Definition.MouseState.X1Down))
                _player.SetForceGotoId(EventID);
            break;
        case SharpHook.Native.MouseButton.Button5:
            if (MouseState.Contains(Definition.MouseState.X2Down))
                _player.SetForceGotoId(EventID);
            break;
    }

    if (SuppressEvent)
        e.SuppressEvent = false;
}

 

이제 완성된 코드를 테스트 해볼건데요. 테스트용 스크립트는 아래와 같은 구조입니다.

 

 

이벤트를 가장 위에 등록해놓고, 체크할 마우스 상태를 하나 추가합니다. 그리고, 지연 b와 액션이동으로 스크립트가 완료되지 않도록 무한 반복시킵니다. 스크립트를 실행하고, 마우스 상태를 등록한 키(마우스 왼쪽 또는 오른쪽등등...)를 누르면 이벤트가 발생하고, 이벤트가 발생했을 때 이동할 아이디로 루틴이 이동하는지 확인합니다. 이벤트가 발생했을 때 이동할 루틴은 스크립트의 마지막 그룹 c입니다.

 

테스트에 대한 내용은 아래 동영상을 참고하세요.

https://youtu.be/JfdHc12wDfU

 

 

https://youtu.be/hgVijX0o1WA

 

 

https://youtu.be/F_XocXTg1Os

 

 

마우스와 키보드 후킹 관련된 이벤트를 어디에 사용할지는 모르겠지만, 잘 사용하면 업무에 도움이 될수도 있을듯 합니다. 다음에는 이벤트 범위도 설정해보도록 할께요. 그리고, 키보드 관련된 내용도 같이 다루면 좋겠네요. 다음 내용도 많이 기대해주세요^^

 

[ 각종 자동화 매크로 및 RPA 프로그램 제작 해드립니다. ]

[ 초보자도 쉽게 따라할 수 있는 기초 학습 강좌 보기 ]

 

원본 글 보기

http://ngmsoftware.com/bbs/board.php?bo_table=tip_and_tech 

 

엔지엠소프트웨어

엔지엠 매크로는 복잡한 반복작업을 자동화할 수 있습니다. PC 게임, 모바일 게임을 최적으로 지원하며 모든 PC 프로그램 및 업무에 적용할 수 있습니다.

www.ngmsoftware.com

 

반응형

댓글