C#/C# 리니지m/

C#으로 만드는 리니지m 매크로 (1)이미지서치

2019. 9. 27.

2019/09/25 - [프로그래밍/C# 프로그래밍] - C# Dll Import와 핸들러획득

2019/09/27 - [프로그래밍/C# 프로그래밍] - C# spy++를 이용한 핸들러획득

 

이미지 서치

참고글을 활용하여 앱플레이어의 화면을 비활성상태(최소화x 다른창에가려짐o)

출력해보겠습니다.

앞으로의 매크로 코딩에 기본이되는 이미지서치입니다.

 

대표적인 앱플레이어에는 LDPlayer(舊 모모)와 Nox플레이어가 있습니다.

(사실 차이가 거의 없습니다. 필자는 LDPlayer를 써서 기본설명은 LD입니다.)

 

우선 새로운 프로젝트를 하나 만듭니다.

필자는 imagesearch 라고 만들었습니다.

폼화면에 picturebox1개(사이즈는 1280,720)textbox, button 한개 씩 만들어줍니다.

picturebox가 다보일수 있도록 메인창크기도 충분히 크게해줍시다.

button을 더블클릭하여 클릭이벤트를 만들면서 코딩창으로 넘어갑니다.

 
using System.Runtime.InteropServices;

public partial class Form1 : Form
    {
        [DllImport("User32", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);

        [DllImport("user32")]
        private static extern IntPtr FindWindowEx(IntPtr hWnd1, int hWnd2, string lp1, string lp2);

        [DllImport("user32.dll")]
        internal static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcblt, int nFlags);

        public Form1()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {

        }
    }

 

using문 추가해주시고 Dllimport 3가지 추가해줍니다.

Findwindow는 부모핸들 찾는 함수

FindwindowEX는 자식핸들 찾는 함수

Printwindow는 이미지에 그려주는 함수입니다.

 

이제 Spy++를 실행해 앱플레이어의 핸들정보를 찾아봅시다.

 

여기서 확인해야하는정보는 "TheRender""RenderWindow" 입니다.

(Nox의 경우 "ScreenBoardClassWindow""Qt5QWindowIcon" 입니다.)

 

이제 코딩해봅시다.

private void Button1_Click(object sender, EventArgs e)
        {
            string a = textBox1.Text;

            IntPtr b = FindWindow(null, a);

            IntPtr c = FindWindowEx(b, 0, "RenderWindow", "TheRender");
            //녹스앱플레이어를 쓴다면
            //IntPtr c = FindWindowEx(b, 0, "Qt5QWindowIcon", "ScreenBoardClassWindow");

            Graphics gdata = Graphics.FromHwnd(c);

            Rectangle rect = Rectangle.Round(gdata.VisibleClipBounds);

            Bitmap bmp = new Bitmap(rect.Width, rect.Height);

            using (Graphics g = Graphics.FromImage(bmp))
            {
                IntPtr hdc = g.GetHdc();
                PrintWindow(c, hdc, 0x2);
                g.ReleaseHdc(hdc);
            }

            pictureBox1.Image = bmp;
        }

 

a변수에 textbox1의 텍스트값(앱플레이어이름)을 저장하고

a를 통해 부모핸들을 찾아 b에 저장.

부모핸들b와 자식핸들정보를이용해 자식핸들 획득 c에저장.

c와 PrintWindow를 이용하여 이미지생성.

최종적으로 그려진이미지를 picturebox1에 출력 하는 코드입니다.

 

이와 같이 캡처 되었다면 성공입니다!

 

더보기

전체코드

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace imagesearch
{
    public partial class Form1 : Form
    {
        [DllImport("User32", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);

        [DllImport("user32")]
        private static extern IntPtr FindWindowEx(IntPtr hWnd1, int hWnd2, string lp1, string lp2);

        [DllImport("user32.dll")]
        internal static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcblt, int nFlags);

        public Form1()
        {
            InitializeComponent();
        }
        
        private void Button1_Click(object sender, EventArgs e)
        {
            string a = textBox1.Text;

            IntPtr b = FindWindow(null, a);

            IntPtr c = FindWindowEx(b, 0, "RenderWindow", "TheRender");

            Graphics gdata = Graphics.FromHwnd(c);

            Rectangle rect = Rectangle.Round(gdata.VisibleClipBounds);

            Bitmap bmp = new Bitmap(rect.Width, rect.Height);

            using (Graphics g = Graphics.FromImage(bmp))
            {
                IntPtr hdc = g.GetHdc();
                PrintWindow(c, hdc, 0x2);
                g.ReleaseHdc(hdc);
            }

            pictureBox1.Image = bmp;
        }
    }
}