ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C# - WindowForm user32를 활용한 메모장 스크린샷 프로그램
    C# 2022. 1. 22. 16:27
    반응형

    사용하고나 사용할 예정인 user32에 대한 조사를 했습니다.

     

    GetWindowPlacement

    -> 윈도우의 위치, 크기, 최대/최소화 상태를 한꺼번에 조사

    -> 시스템은 내부적으로 윈도우의 좌표를 두쌍의 좌표와 한개의 사각형으로 기억

     

    GetWindowRect

    - 작업 영역의 크기 얻음

     

    FindWindow

    - 프로세스의 핸들을 찾아 반환한다.

     

    PrintWindow

    - 캡처를 원하는 창의 핸들과 DC(Device Context), 옵션 이렇게 3가지의 인수를 넘기면 해당창을 캡처한 비트맵 핸들을 반환한다.

     

    GetWindowRgn

    - 특성창의 크기 가져오기

     

    CreateRectRgn

    - 그래픽상의 크기 가져오기 

     

     

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace MemoScreenShotDLLControlEx
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            // 프로세스 핸들 찾기
            [DllImport("user32.dll")]
            public static extern int FindWindow(string lpClassName, string lpWindowName);
    
            //스크린샷
            [DllImport("user32.dll")]
            static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
    
    
            // 프로세스가 존재하는지 여부, 핸들 구하기
            public IntPtr Client_Connection(string clientname)
            {
                IntPtr iResulthwnd = new IntPtr();
                int inthwnd = FindWindow(clientname, null);
                if (inthwnd != 0)
                {
                    iResulthwnd = new IntPtr(inthwnd);
                    MessageBox.Show("해당 프로세스가 열려 있습니다.");
                    
                }
                else
                {
                    iResulthwnd = new IntPtr(inthwnd);
                    MessageBox.Show("해당 프로세스는 현재 존재하지 않습니다.");
                    
                }
                return iResulthwnd;
            }
    
    
            private void button1_Click(object sender, EventArgs e)
            {
    
                IntPtr memoHandle = Client_Connection("notepad");
    
                if (memoHandle.Equals(IntPtr.Zero))
                {
                    return;
                }
    
                //Graphics.FromHwnd(): 지정된 창 핸들에 대한 새 Graphics를 반환
                Graphics gfxWin = Graphics.FromHwnd(memoHandle); 
    
                //Rectangle: 사각형의 위치와 크기를 나타내는 네 정수의 집합을 저장하는 구조체
                //Rectangle.Round(): RectangleF 값을 가장 가까운 정수 값으로 반올림
                Rectangle rc = Rectangle.Round(gfxWin.VisibleClipBounds); 
    
    
                // 픽셀 포맷 정보 얻기 (Optional)
                PixelFormat pixelFormat = PixelFormat.Format32bppArgb;
    
    
                // 화면 크기만큼의 Bitmap 생성
                try
                {
                    //Bitmap 클래스: 그래픽 이미지의 픽셀 데이터를 저장하는 클래스. 픽셀 단위로 데이터를 저장한다.
                    using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, pixelFormat))
                    {
                        // Bitmap 이미지 변경을 위해 Graphics 객체 생성
                        //FromImage(): 지정된 Graphics에 대한 새 Image를 반환하는 메서드
                        using (Graphics gr = Graphics.FromImage(bmp))
                        {
                            //디바이스 컨텍스트에 대한 핸들을 가져온다.
                            IntPtr dc = gr.GetHdc();
    
    
                            bool success = PrintWindow(memoHandle, dc, 0);
                            gr.ReleaseHdc(dc);
                        }
                        bmp.Save("result.bmp");
                        MessageBox.Show("스냅샷 찰영 완료");
                    }
                }
                catch(Exception ex)
                {
                    MessageBox.Show("스냅샷 찰영 오류");
    
                    // 윈도우 폼에서 콘솔을 보기 위해서는 Project -> (파일이름) Properties -> Output Type 변경
                    Console.WriteLine(ex);
                }
                
    
            }
        }
    }

     

     

     

    [결과]

    - 현재 프로세스에 메모장이 없는 경우 FindWindow를 통해서 프로세스 존재여부를 판별한다.

     

     

     

    - 메모장이 현재 실행중인 프로세스에 존재할 경우 PrintWindow를 통해 스크린샷으로 저장되어

     debug 파일 안에 result.bmp 파일로 저장된다.

     

     

     

     

     

    * 단 아직 메모장이 최소화로 비활성창 상태일 경우 스크린샷을 찍지 못한다. 추후 코드 추가할 예정

    300x250

    댓글

Designed by Tistory.