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

C# .NET 매크로 프로그램 만들기. (비활성 마우스 이펙트 보기)

by 업무자동화 2024. 6. 17.
반응형

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

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을 업그레이드 한다는 느낌으로 여러가지 GUI 관련 기능을 추가하고 있어요. 아무래도 단순 반복 작업을 하는 것보다는 GUI를 개선할 방법을 고민하고, 기능을 구현하는게 더 재미있긴 합니다.

 

매크로 프로그램은 활성 모드와 비활성 모드로 나뉩니다. 활성 모드는 하드웨어 방식과 소프트웨어 방식 2가지가 있는데요. 하드웨어 방식은 또다시 3가지로 나뉩니다. 엔지엠 매크로에서는 디디와 인터셉션 그리고, 시리얼 통신을 제공하고 있습니다. 비활성 모드는 윈도우 API를 이용하는 SendMessage와 PostMessage입니다. 둘다 로직은 동일하지만 동기 모드와 비동기 모드로 나뉩니다. 비활성 모드는 일부 프로그램에서 정상 동작하지 않습니다. 해당 API를 막거나 소프트웨어 신호를 감지해서 입력을 막기 때문입니다. 그래서, 대부분은 하드웨어 모드로 사용하고 있습니다.

 

우선, 엔지엠 매크로에서 이펙트를 보기 위한 옵션을 추가 해줍니다. 옵션은 에디터와 플레이어가 구분되어 있기 때문에 에디터용 사용자 컨트롤을 추가 했습니다.

 

 

사용자 컨트롤의 디자인은 아래와 같습니다. 나중에 항목이 하나 더 추가될 수 있습니다.

 

 

컨트롤은 하나의 기능만 제공하고 있습니다. 속성을 하나 열어주면 될거 같네요.

using Ai.Common.Client.Interface;

namespace Ai.Common.Client.OptionItem
{
    public partial class EditorMouseEffectItem : UserControl, IMouseEffectItem
    {
        public bool UseMouseEffect { get { return this.chkMouseEffect.Checked; } set { this.chkMouseEffect.Checked = value; } }

        public EditorMouseEffectItem()
        {
            InitializeComponent();

            pnlHelper.BackgroundImage = (Image)Ai.ResourceManager.ImageResource.Instance.GetObject("question");
            pnlHelper.BackgroundImageLayout = ImageLayout.Center;
        }
    }
}

 

 

옵션 뷰 또는 팝업을 표시할 컨테이너에 행을 하나 추가 했습니다. 이 행에 위에서 만든 사용자 컨트롤(UserControl)을 추가해야 합니다.

 

 

컨테이너에서 접근할 수 있도록 추가한 컨트롤의 속성을 한번 더 열어줍니다.

public bool UseMouseEffect
{
    get
    {
        return ((Interface.IMouseEffectItem)this.tableLayoutPanel.Controls.Find("effect", true).First()).UseMouseEffect;
    }
    set
    {
        ((Interface.IMouseEffectItem)this.tableLayoutPanel.Controls.Find("effect", true).First()).UseMouseEffect = value;
    }
}

 

위 속성을 구현하는 부분은 생성자에서 처리합니다. 지금까지 추가했던 모든 옵션 컨트롤이 추가되어 있습니다. 플레이어도 에디터만큼 옵션들을 추가해야 하지만, 현재는 2개만 만들어 놓았습니다. 나중에 플레이어를 개발할 때 모두 추가해야 하는데요. 지금은... 단순 테스트만 해보고, 넘어갔어요. 일단 기본 기능을 구현하는게 더 급하니까요.

public Option(Ai.Interface.IClient client)
{
    _client = client;
    _optionModel = Ai.Api.ModelHelper.Load<Ai.Model.Client.OptionModel>(Path.Combine(System.Windows.Forms.Application.StartupPath, Ai.Definition.ConfigDirectory, Ai.Definition.OptionFileName, Ai.Definition.ConfigFileExtension));
    InitializeComponent();

    if (client is Ai.Interface.IEditor)
    {
        this.tableLayoutPanel.Controls.Add(new OptionItem.EditorTitleItem(_client) { Name = "title", Dock = DockStyle.Fill }, 0, 0);
        this.tableLayoutPanel.Controls.Add(new OptionItem.EditorSetDirectoryItem() { Name = "directory", Dock = DockStyle.Fill }, 0, 1);
        this.tableLayoutPanel.Controls.Add(new OptionItem.EditorScaleItem() { Name = "scale", Dock = DockStyle.Fill }, 0, 2);
        this.tableLayoutPanel.Controls.Add(new OptionItem.EditorCaptureModeItem() { Name = "captureMode", Dock = DockStyle.Fill }, 0, 3);
        this.tableLayoutPanel.Controls.Add(new OptionItem.EditorSyncItem() { Name = "sync", Dock = DockStyle.Fill }, 0, 4);
        this.tableLayoutPanel.Controls.Add(new OptionItem.EditorMouseEffectItem() { Name = "effect", Dock = DockStyle.Fill }, 0, 5);
    }
    else if (client is Ai.Interface.IPlayer)
    {
        this.tableLayoutPanel.Controls.Add(new OptionItem.PlayerScaleItem() { Name = "scale", Dock = DockStyle.Fill }, 0, 1);
        this.tableLayoutPanel.Controls.Add(new OptionItem.PlayerCaptureModeItem() { Name = "captureMode", Dock = DockStyle.Fill }, 0, 2);
    }
}

 

MouseEffectForm을 엔진의 클라이언트에 추가 해줍니다. MouseEffectForm은 이름처럼 마우스 클릭 위치에 이펙트를 보여주기 위한 GUI입니다.

 

 

타이머를 이용해서 동그라미를 그려줍니다.

public MouseEffectForm()
{
    _timeCheck = 0;
    _timeLimit = 250;
    _timer = new System.Windows.Forms.Timer { Interval = 25, Enabled = false };
    _timer.Tick += OnTimerTicked;
    _pen1 = new Pen(Color.Orange, 4);
    _pen2 = new Pen(Color.Blue, 3);
    _rect1 = new Rectangle(1, 1, 27, 27);
    _rect2 = new Rectangle(10, 10, 10, 10);

    FormBorderStyle = FormBorderStyle.None;
    BackColor = Color.White;
    TransparencyKey = Color.White;
    TopLevel = true;
    TopMost = true;
    VisibleChanged += Effector_VisibleChanged;
    Paint += Effector_Paint;
}

 

폼의 그래픽 개체로 동그라미를 그려줍니다.

private void DrawEllipseRectangle(PaintEventArgs e)
{
    int alpha = 255;
    alpha -= _timeCheck > 255 ? 255 : _timeCheck;
    _pen2.Color = Color.FromArgb(alpha, _pen2.Color);
    _pen1.Color = Color.FromArgb(alpha, _pen1.Color);
    e.Graphics.DrawEllipse(_pen2, _rect2);
    e.Graphics.DrawEllipse(_pen1, _rect1);
}

 

참고로, 폼을 실행할 때 사용자에게 표시하지 않아야 합니다. 그래서, 폼 인스턴스를 생성하면서 Taskbar에서 숨겨야 합니다. 그리고, Manager는 초기화 지연 인스턴스이기 때문에 실행되기 전에는 핸들이 만들어지지 않습니다. 따라서, 메니저의 생성자에서 폼을 인스턴스화 하더라도 핸들이 만들어지지 않았을 가능성이 있습니다. 실제로 테스트를 해보면 핸들이 만들어지기 전에 스크립트가 먼저 실행되어 에러가 발생합니다.

MouseEffector = new Client.MouseEffectForm();
MouseEffector.ShowInTaskbar = false;

if (!this.MouseEffector.IsHandleCreated)
    Ai.Api.ApiHelper.CreateHandle(this.MouseEffector.Handle);

 

이와 같은 시나리오에서 특정 폼의 핸들을 강제로 만들려면 아래와 같이 CreateHandle 메소드를 하나 만들어서 호출해주면 됩니다.

public static void CreateHandle(IntPtr handle)
{
    int exstyle = Ai.Api.Core.User32.GetWindowLong(handle, (int)Options.WindowPropertyChangeCommand.GWL_EXSTYLE);
    exstyle |= (int)Options.ExtendedWindowStyles.WS_EX_TRANSPARENT;
    Ai.Api.Core.User32.SetWindowLong(handle, (int)Options.WindowPropertyChangeCommand.GWL_EXSTYLE, exstyle);
}

 

이제 마지막으로 마우스 클릭 액션 아래에 아래와 같이 옵션을 읽어서 마우스 이펙트를 표시할지 여부를 판단해야 합니다. 그리고, 마우스 이펙트를 표시한다면 활성 모드인지 비활성 모드인지에 따라서 좌표를 보정해줘야 합니다.

if (player.Manager.UseMouseEffect)
{
    System.Drawing.Point effectPoint = position;

    if ((inputType == Definition.DeviceInputType.PostMessage || inputType == Definition.DeviceInputType.SendMessage) &&
        controlHandle.HasValue && controlHandle.Value != IntPtr.Zero)
        effectPoint = ActiveMouseLocation(controlHandle.Value, position);
    
    player.Manager.ShowMouseEffect(effectPoint);
}

 

이제 테스트를 해볼까요? 아래 유튜브 동영상을 참고해서 녹스 앱플레이어를 비활성으로 클릭하고, 마우스 이펙트 표시 여부도 확인 해보세요.

https://youtu.be/PS8U9fa7rho

 

 

 

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

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

 

원본 글 보기

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

 

엔지엠소프트웨어

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

www.ngmsoftware.com

 

반응형

댓글