첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
------------------------------------------------------------------------------------------------------------------------------------------------------
728x90
728x170

■ WIN32 API를 사용해 화면을 캡처하는 방법을 보여준다.

TestProject.zip
0.01MB

▶ GDI32Helper.cs

using System;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// GDI32 헬퍼
    /// </summary>
    public static class GDI32Helper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// SRC_COPY
        /// </summary>
        public const int SRC_COPY = 0x00CC0020;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Statuc
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 비트 복사하기 - BitBlt(targetDCHandle, targetX, targetY, width, height, sourceDCHandle, sourceX, sourceY, rasterOperation)

        /// <summary>
        /// 비트 복사하기
        /// </summary>
        /// <param name="targetDCHandle">타겟 DC 핸들</param>
        /// <param name="targetX">타겟 X</param>
        /// <param name="targetY">타겟 Y</param>
        /// <param name="width">너비</param>
        /// <param name="height">높이</param>
        /// <param name="sourceDCHandle">소스 DC 핸들</param>
        /// <param name="sourceX">소스 X</param>
        /// <param name="sourceY">소스 Y</param>
        /// <param name="rasterOperation">래스터 작업</param>
        /// <returns>처리 결과</returns>
        [DllImport("gdi32")]
        public static extern long BitBlt(IntPtr targetDCHandle, int targetX, int targetY, int width, int height, IntPtr sourceDCHandle,
            int sourceX, int sourceY, int rasterOperation);

        #endregion
        #region 호환 비트맵 생성하기 - CreateCompatibleBitmap(dcHandle, width, height)

        /// <summary>
        /// 호환 비트맵 생성하기
        /// </summary>
        /// <param name="dcHandle">DC 핸들</param>
        /// <param name="width">너비</param>
        /// <param name="height">높이</param>
        /// <returns>비트맵 핸들</returns>
        [DllImport("gdi32")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr dcHandle, int width, int height);

        #endregion
        #region 호환 DC 생성하기 - CreateCompatibleDC(dcHandle)

        /// <summary>
        /// 호환 DC 생성하기
        /// </summary>
        /// <param name="dcHandle">DC 핸들</param>
        /// <returns>DC 핸들</returns>
        [DllImport("gdi32")]
        public static extern IntPtr CreateCompatibleDC(IntPtr dcHandle);

        #endregion
        #region DC 삭제하기 - DeleteDC(dcHandle)

        /// <summary>
        /// DC 삭제하기
        /// </summary>
        /// <param name="dcHandle">DC 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("gdi32")]
        public static extern bool DeleteDC(IntPtr dcHandle);

        #endregion
        #region 객체 삭제하기 - DeleteObject(objectHandle)

        /// <summary>
        /// 객체 삭제하기
        /// </summary>
        /// <param name="objectHandle">객체 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("gdi32")]
        public static extern bool DeleteObject(IntPtr objectHandle);

        #endregion
        #region 객체 선택하기 - SelectObject(dcHandle, objectHandle)

        /// <summary>
        /// 객체 선택하기
        /// </summary>
        /// <param name="dcHandle">DC 핸들</param>
        /// <param name="objectHandle">객체 핸들</param>
        /// <returns>이전 핸들</returns>
        [DllImport("gdi32")]
        public static extern IntPtr SelectObject(IntPtr dcHandle, IntPtr objectHandle);

        #endregion
    }
}

 

▶ USER32Helper.cs

using System;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// USER32 헬퍼
    /// </summary>
    public static class USER32Helper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 데스크톱 윈도우 구하기 - GetDesktopWindow()

        /// <summary>
        /// 데스크톱 윈도우 구하기
        /// </summary>
        /// <returns>윈도우 핸들</returns>
        [DllImport("user32")]
        public static extern IntPtr GetDesktopWindow();

        #endregion
        #region 윈도우 DC 구하기 - GetWindowDC(windowHandle)

        /// <summary>
        /// 윈도우 DC 구하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <returns>DC 핸들</returns>
        [DllImport("user32")]
        public static extern IntPtr GetWindowDC(IntPtr windowHandle);

        #endregion
        #region DC 해제하기 - ReleaseDC(windowHandle, dcHandle)

        /// <summary>
        /// DC 해제하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <param name="dcHandle">DC 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("user32")]
        public static extern IntPtr ReleaseDC(IntPtr windowHandle, IntPtr dcHandle);

        #endregion
        #region 윈도우 사각형 구하기 - GetWindowRect(windowHandle, rectangle)

        /// <summary>
        /// 윈도우 사각형 구하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <param name="rectangle">사각형</param>
        /// <returns>처리 결과</returns>
        [DllImport("user32")]
        public static extern IntPtr GetWindowRect(IntPtr windowHandle, ref RECT rectangle);

        #endregion
    }
}

 

▶ UIHelper.cs

using System;
using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// UI 헬퍼
    /// </summary>
    public static class UIHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 화면 캡처하기 - CaptureScreen(sourceWindowHandle)

        /// <summary>
        /// 화면 캡처하기
        /// </summary>
        /// <param name="sourceWindowHandle">소스 윈도우 핸들</param>
        /// <returns>이미지</returns>
        public static Image CaptureScreen(IntPtr sourceWindowHandle)
        {
            IntPtr sourceDCHandle = USER32Helper.GetWindowDC(sourceWindowHandle);

            RECT rectangle = new RECT();

            USER32Helper.GetWindowRect(sourceWindowHandle, ref rectangle);

            int width  = rectangle.Right  - rectangle.Left;
            int height = rectangle.Bottom - rectangle.Top;

            IntPtr targetDCHandle = GDI32Helper.CreateCompatibleDC(sourceDCHandle);

            IntPtr bitmapHandle = GDI32Helper.CreateCompatibleBitmap(sourceDCHandle, width, height);

            IntPtr previousObjectHandle = GDI32Helper.SelectObject(targetDCHandle, bitmapHandle);

            GDI32Helper.BitBlt(targetDCHandle, 0, 0, width, height, sourceDCHandle, 0, 0, GDI32Helper.SRC_COPY);

            GDI32Helper.SelectObject(targetDCHandle, previousObjectHandle);

            GDI32Helper.DeleteDC(targetDCHandle);

            USER32Helper.ReleaseDC(sourceWindowHandle, sourceDCHandle);

            Image image = Image.FromHbitmap(bitmapHandle);

            GDI32Helper.DeleteObject(bitmapHandle);

            return image;
        }

        #endregion
    }
}

 

▶ MainForm.cs

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.captureButton.Click += captureButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 캡처하기 버튼 클릭시 처리하기 - captureButton_Click(sender, e)

        /// <summary>
        /// 캡처하기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void captureButton_Click(object sender, EventArgs e)
        {
            try
            {
                WindowState = FormWindowState.Minimized;

                Image previousImage = this.pictureBox.Image;

                this.pictureBox.Image = null;

                if(previousImage != null)
                {
                    previousImage.Dispose();

                    previousImage = null;
                }

                Thread.Sleep(300);

                IntPtr descktopWindowHandle = USER32Helper.GetDesktopWindow();

                Image image = UIHelper.CaptureScreen(descktopWindowHandle);

                this.pictureBox.Image = image;
            }
            finally
            {
                WindowState = FormWindowState.Normal;
            }
        }

        #endregion
    }
}
728x90
그리드형(광고전용)
Posted by icodebroker
,