NGMsoftware

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

    학습


    C# C# .NET 매크로 프로그램 만들기. (마우스 클릭 기능 확장)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 오늘은 마우스에 랜덤 기능을 추가해보도록 하겠습니다. 지연에는 이미 랜덤이 적용되어 있는데요. 마우스 좌표는 랜덤이 적용되어 있지 않습니다. 그래서, 잠깐 쉬어가는 타임으로 마우스에 랜덤 기능을 추가해봤습니다. 랜덤은 크게 스페셜 랜덤과 일반 랜덤이 있습니다. 우선, 아래와 같이 스크립트를 작성하고 랜덤을 적용시켜봤습니다.

    P0wM346.png

     

     

    그림판을 열고, 좌표를 설정한 후 100회 반복해서 클릭하도록 하겠습니다.

    M36rE9L.png

     

     

    매크로를 실행하면 아래와 같이 좌표가 만들어집니다.

    Eq9KLAE.png

     

     

    이번에는 스페셜 랜덤을 적용시키고, 실행 해볼께요.

    N4bMYf9.png

     

     

    결과는 아래와 같습니다.

    dAv2X2x.png

     

     

    이번에는 비활성 멀티 다클라 환경에서 비활성으로 동작하는 랜덤 마우스입니다. 매크로를 실행하고, 결과를 보면 일부 클릭은 동작하지 않은것처럼 보입니다. 동작은 했는데요. 랜덤 범위가 크다보니 실제 클릭 위치를 벗어나서 그런 현상이 발생합니다. 클릭 좌표에서 화면 범위 안쪽으로 랜덤 값을 설정하면 정상 동작합니다.

     

     

    랜덤 기능은 클릭, 더블 클릭, 마우스 이동, 마우스 드래그에만 적용됩니다. 마우스 다운과 마우스 업은 서로 좌표가 달라지면 드래그와 같은 효과가 나타나기 때문에 랜덤을 적용할 수 없습니다. 마우스 다운과 업도 랜덤하게 사용하려면 추후에 추가될 랜덤 좌표 만들기 액션을 실행해서 결과로 나온 값을 변수에 넣고, 다운과 업에서 같이 사용해야 합니다. 약간 번거로운 작업이긴 하지만, 어쩔 수 없는 부분입니다.

     

    일반적으로는 마우스 다운과 업을 사용하기 보다는 마우스 클릭을 사용하는게 효과적입니다. 그렇지만, 꼭~ 마우스 다운과 업을 사용해야 한다면 마우스 클릭의 다운 업 지연을 설정해서 사용하셔도 됩니다. 하지만, 마우스를 다운한 상태에서 어떤 로직에 의해서 마우스 업을 해야 한다면 마우스 클릭으로는 처리가 불가능합니다. 로직이 중간에 처리되어야 하기 때문에 약간 복잡해지더라도 다운과 업 2개 액션을 조합해야 합니다.

     

    마우스 랜덤 옵션은 모두가 적용되지는 않지만, 어쩔 수 없이 BaseModel에 구현했습니다.

    [LocalizedCategory("UseRandom")]
    [LocalizedDisplayName("UseRandom")]
    [LocalizedDescription("UseRandom")]
    [Browsable(true)]
    [DefaultValue(false)]
    public bool UseRandom { get; set; }
    
    [LocalizedCategory("UseRandom")]
    [LocalizedDisplayName("RandomPointMin")]
    [LocalizedDescription("RandomPointMin")]
    [Browsable(true)]
    [DefaultValue(0)]
    public int RandomPointMin { get; set; }
    
    [LocalizedCategory("UseRandom")]
    [LocalizedDisplayName("RandomPointMax")]
    [LocalizedDescription("RandomPointMax")]
    [Browsable(true)]
    [DefaultValue(0)]
    public int RandomPointMax { get; set; }
    
    [LocalizedCategory("UseRandom")]
    [LocalizedDisplayName("RandomPointOption")]
    [LocalizedDescription("RandomPointOption")]
    [Browsable(true)]
    [DefaultValue(typeof(Definition.PointFormulaOption), "All")]
    public Definition.PointFormulaOption Options { get; set; } = Definition.PointFormulaOption.All;

     

    랜덤을 사용하지 않는 마우스 다운과 업 그리고, 휠은 아래와 같이 맴버를 숨겨야 합니다.

    [Browsable(false)]
    public new bool UseRandom { get; set; }
    
    [Browsable(false)]
    public new int RandomPointMin { get; set; }
    
    [Browsable(false)]
    public new int RandomPointMax { get; set; }
    
    [Browsable(false)]
    public new Definition.PointFormulaOption Options { get; set; }

     

    만드는김에 마우스 클릭의 반복 처리도 추가 해줍니다.

    [LocalizedCategory("Repeat")]
    [LocalizedDisplayName("CompareRepeat")]
    [LocalizedDescription("CompareRepeat")]
    [Browsable(true)]
    [DefaultValue(1)]
    public int RepeatCount { get; set; } = 1;
    
    [LocalizedCategory("Repeat")]
    [LocalizedDisplayName("CompareRepeatTerm")]
    [LocalizedDescription("CompareRepeatTerm")]
    [Browsable(true)]
    [DefaultValue(0)]
    public int RepeatInterval { get; set; }

     

    마우스 반복은 클릭 액션에만 존재합니다. 마우스 클릭 반복이 2회면 더블 클릭과 동일합니다.

    ※ 일부 환경에서는 더블 클릭과 클릭 두번이 다른 명령으로 인식합니다.

     

    마우스 다운과 마우스 업의 경우에는 반복이 필요하지 않습니다. 반복을 하더라도 윈도우에서 처리가 되지 않기 때문입니다. 그리고, 휠의 경우 자체적으로 휠을 굴리는 틱에 대한 반복이 따로 존재합니다. 동작의 반복과는 다른 개념이기 때문입니다. 아무튼, 제가 예상하지 못한 어떤 동작이나 로직이 있을수도 있는데요. 지금은 상상력이 부족해서 여기까지만 기능을 추가했습니다.

     

    랜덤을 처리하기 위해 따로 원본 좌표를 복사해둬야 합니다.

    Point offsetCoordinate = this.Coordinate;
    offsetCoordinate.Offset(player.Offset);

     

    원본 좌표에 누적되면 랜덤 값이 계속해서 증가합니다. 그렇기 때문에 원본 좌표는 다시 반복할 때 초기화된 값을 사용할 수 있도록 해줍니다.

    for (int i = 0; i < RepeatCount; i++)
    {
        Point coordinate = offsetCoordinate;

     

    랜덤 옵션이 적용된 상태라면 닷넷의 Random 개체를 이용해서 Next 메소드로 값을 가져옵니다.

    if (UseRandom)
        coordinate.Offset(Ai.Common.Helper.RandomPosition(
        RandomPointMin, RandomPointMax, Options, player.UseSpecialRandomLocation, player.SpecialRandomLocationMean));

     

    비활성 모드에서는 아래와 같이 별도로 처리해야 합니다.

    var coord = InactiveMouseLocation(handle, this._windowRect, coordinate);

     

    비활성 모드에서는 각각의 창마다 위치가 존재하고, 이전 위치와 현재 위치를 비교해서 좌표값을 시프트 시켜줘야 합니다. 이렇게 해야 창이 이동하더라도 원본 위치와 동일한 곳을 클릭할 수 있습니다. 마우스 클릭뿐만 아니라 다른 마우스 동작들도 동일한 로직을 따르고 있습니다.

     

    비활성 좌표를 계산하는 방법은 간단합니다. 원본 좌표가 되는 창 위치를 기억하고 있다가 현재 적용해야 하는 창의 위치에서 원본 위치를 빼고, 다시 현재 위치를 빼면 창이 이동한 만큼의 거리를 알아낼 수 있습니다. 그림으로 그려보면 간단한데... 글로는 잘 이해가 안갈수도 있을거 같네요. 그림판과 같은 곳에 사각형을 2개 그려놓고, 사각형이 이동한만큼의 거리를 어떻게 계산해야 할지 고민을 해보세요. 그러면, 아래 코드가 금방 이해가 될겁니다^^

    protected virtual Point InactiveMouseLocation(IntPtr currentHandle, Rectangle initialRect, Point mousePoint)
    {
        Ai.Common.Windows.GetWindowRect(currentHandle, out Rectangle currentRect);
        mousePoint.Offset(currentRect.X - initialRect.X - currentRect.X, currentRect.Y - initialRect.Y - currentRect.Y);
        return mousePoint;
    }

     

    이렇게해서 마우스 클릭 기능에 반복과 랜덤 좌표를 계산해서 동작하는 로직을 완성했습니다. 사실, 대부분의 계산이 산수정도의 수준이라서 크게 어렵거나 복잡한 부분은 없었을겁니다. 대부분은 응용이거든요. 기능을 개발할 때 로직을 세우고, 아이디어가 있으면 그걸 적용시켜보는게 좋습니다. 만약, 복잡한 계산이나 로직이 필요하면 여전히 구글에 물어보고, 검증된 잘 만들어진 코드를 가져다가 약간의 수정만 하면 됩니다. 요즘은 코딩을 구글이 다 하니까요^^

     

    개발자에게 후원하기

    MGtdv7r.png

     

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

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

    감사합니다~

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

    댓글목록

    등록된 댓글이 없습니다.