티스토리 뷰

이번에는 실행 중인 프로세스를 찾아서 해당 프로세스에 키값을 넘겨주는 것을 진행하도록 하겠습니다.

 

1
2
3
4
5
        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "SetForegroundWindow")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
cs

 

DLL 을 추가하여 위 2가지 API 를 사용할수 있게 선언해줍니다.

 

FindWindow 로 현재 실행중이 앱플레이어를 찾습니다. (모모앱플레이어 기준으로 작성하도록 하겠습니다.)

SetForegroundWindow 로 플레이어로 포커스를 가져옵니다.

 

 

 

플레이어를 지정해줄 TextBox를 하나 추가해주세요

 

1
2
            IntPtr procHandler = FindWindow(null, textBox6.Text);
            SetForegroundWindow(procHandler);
cs

 

TextBox 에서 프로세스 이름을 가져와 포커스를 가져옵니다.

 

1
2
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern void keybd_event(uint vk, uint scan, uint flags, uint extraInfo);
cs

 

위에 키보드 이벤트를 발생시켜줄  api 를 추가합니다.

추가로 발생시킬 키를 설정할 button 을 하나 추가한 후에 아래 번개 모양을 클릭해줍니다.

 

추가후 keydown에 button2_down 을 추가해줍니다.

 

Keys 를 하나 선언해줍니다.

Keys returnKey;

1
2
3
4
5
        private void button2_down(object sender, KeyEventArgs e)
        {
            returnKey = e.KeyCode;
            button2.Text = e.KeyCode.ToString();
        }
cs

 

해당 button2 을 누르고 원하는 키를 입력하면 아래와 같이 설정되는걸 확인할수 있습니다.

 

이제 해당 키를 발생시키도록 하겠습니다.

 

1
2
3
4
5
6
7
8
9
        System.Windows.Forms.Timer timer;
 
        public Form1()
        {
            InitializeComponent();
            timer = new System.Windows.Forms.Timer();
            timer.Interval = 3000;
            timer.Tick += new EventHandler(check);
        }
cs

 

3초에 한번씩 체크하기 위해 위와같이 타이머를 추가했습니다.

 

PrintScreenAndCheck 함수를 작성합니다.

강의 1,2 번에서 진행한 화면을 캡쳐해서 숫자를 인식하는 코드와

숫자 인식율을 올리기위해서 RGB 값을 체크해 흰부분을 제외하고는 검은색 처리하는 코드가 들어가 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
        public void PrintScreenAndCheck()
        {
            System.Drawing.Size mSize = new System.Drawing.Size(mWidth, mHeigt);
            Bitmap image = new Bitmap(mWidth, mHeigt);
            Graphics g = Graphics.FromImage(image);
 
            try
            {
                g.CopyFromScreen(mX, mY, 00, mSize);
            }
            catch (Win32Exception w)
            {
                Console.WriteLine(w.Message);
            }
 
            int R, G, B = 0;
 
            for (int i = 0; i < image.Width; i++)
            {
                for (int j = 0; j < image.Height; j++)
                {
                    Color c = image.GetPixel(i, j);
                    R = c.R;
                    G = c.G;
                    B = c.B;
 
                    if (R > 160 && G > 160 && B > 160)
                    {
                        image.SetPixel(i, j, Color.White);
                    }
                    else
                    {
                        image.SetPixel(i, j, Color.Black);
                    }
 
                }
            }
 
            image = ResizeImage(image, pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = image;
 
            image.Save("save.jpg"System.Drawing.Imaging.ImageFormat.Jpeg);
 
            var engine = new TesseractEngine(@"./tessdata""eng", EngineMode.Default);
            Pix pix = Pix.LoadFromFile("save.jpg");
            var result = engine.Process(pix);
            String HpString = result.GetText();
            String[] split = HpString.Split('/');
 
            if (split.Length > 1)
            {
                HpString = split[0];
            }
 
            label1.Text = HpString;
        }
cs

 

 

리니지M 게이지마가 1235/1358 이런식으로 리턴하기때문에 / 아래는 날리고 앞에 현재 에너지 상태만 가져오도록 추가했습니다.

 

이제 3초에 한번씩 위 함수를 호출한 후 에너지 설정한 값보다 작다면 설정한 키를 호출하도록 하겠습니다.

타이머에 추가해준 check 함수를 작성합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        void check(object sender, EventArgs e)
        {
            Console.WriteLine("check");
            PrintScreenAndCheck();
            int Hp = 0;
            int Hplimit = 0;
            try
            {
                Hp = Convert.ToInt32(label1.Text);
                Hplimit = Convert.ToInt32(textBox2.Text);
 
                if(Hp < Hplimit)
                {
                    keybd_event((byte)returnKey, 00x000);
                    Delay(100);
                    keybd_event((byte)returnKey, 00x020);
                }
            }
            catch (System.FormatException w)
            {
                Console.WriteLine(w.Message);
            }
        }
cs

 

모모앱플레이어의 경우 키 다운 업 사이제 Delay를 안주면 인식을 안합니다.

 

 

매크로 강좌는 여기까지입니다.

감사합니다.

댓글