728x90
728x170
■ WIN32 API를 사용해 화면을 캡처하는 방법을 보여준다.
▶ 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
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 크로스 스레드(Cross Thread) 처리하기 (0) | 2018.03.04 |
---|---|
[C#/WINFORM] USB 제어하기 (0) | 2018.03.03 |
[C#/WINFORM] 폼 위치 설정하기 (0) | 2018.03.03 |
[C#/WINFORM] 태스크바 위치 타입 구하기 (0) | 2018.03.03 |
[C#/WINFORM] ClickOnce 설치 파일 캐시 지우기 (0) | 2018.03.01 |
[C#/WINFORM] TextBox 클래스 : 텍스트 필터 사용하기 (0) | 2018.02.18 |
[C#/WINFORM] 카메라 컨트롤 사용하기 (0) | 2018.02.18 |
[C#/WINFORM] DataGridView 클래스 : 달력 컨트롤 컬럼 사용하기 (0) | 2018.02.18 |
[C#/WINFORM] DataGridView 클래스 : 동적 콤보 박스 컬럼 사용하기 (0) | 2018.02.18 |
[C#/WINFORM] TreeView 클래스 : 동적 노드 생성하기 (0) | 2018.02.18 |