Windows/MFC
[ MFC ] CDC와 DC 클래스 사용하기
Soso Dev
2019. 4. 7. 20:46
반응형
1. CDC와 DC 클래스 사용하기
1. CDC란?
CDC는 Device Context를 다루는 MFC의 기본 클래스입니다.
디바이스 컨텍스트(DC)는 출력 장치(화면, 프린터 등)에 그리기 작업을 수행하기 위한 정보 집합입니다.
즉, 선 그리기, 텍스트 출력 등 GDI(Graphics Device Interface) 작업을 하기 위한 인터페이스 역할을 합니다.
- 화면 출력
- 프린터 출력
- 메모리 DC 관리 등
모든 그리기 작업의 기반이 됩니다.
2. CWindowDC
- 윈도우의 전체 영역 (캡션바, 메뉴, 테두리, 클라이언트 영역 포함) 을 대상으로 출력할 때 사용합니다.
- 보통 시스템 정보 등을 포함하여 전체 윈도우를 그릴 필요가 있을 때 사용됩니다.
void CMyView::DrawWindowBorder()
{
CWindowDC dc(this); // 전체 윈도우 DC 획득
dc.Rectangle(0, 0, 200, 200); // 전체 테두리 그리기
}
3. CClientDC
- 윈도우의 Client 영역만을 대상으로 그릴 때 사용합니다.
- 보통 클릭 이벤트, 마우스 이동 등에서 간단한 그림 출력에 사용됩니다.
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CClientDC dc(this); // 클라이언트 영역 DC
dc.TextOutW(point.x, point.y, L"Clicked!");
}
4. CPaintDC
- WM_PAINT 메시지에 응답하여 그릴 때 사용하는 DC입니다.
- 클리핑 영역(실제로 다시 그려야 하는 부분)만 처리하므로 효율적입니다.
- 반드시 BeginPaint와 EndPaint 호출이 필요한데, CPaintDC는 이를 자동 처리해줍니다.
void CMyView::OnPaint()
{
CPaintDC dc(this); // WM_PAINT 메시지용 DC
dc.TextOutW(10, 10, L"OnPaint!");
}
5. 참고: 모든 윈도우는 DC를 가지고 있다
- 윈도우는 내부적으로 출력을 위한 DC를 하나 이상 가지고 있으며, 그 DC는 시스템에 의해 관리됩니다.
- GDI 객체(펜, 브러시, 폰트 등)는 DC가 있어야 실제로 화면에 출력됩니다.
2. 예제 요약
클래스 설명 사용 시점 예제 메서드
CWindowDC | 전체 윈도우 영역을 그림 | 전체 출력 필요 시 | DrawWindowBorder() |
CClientDC | 클라이언트 영역만 그림 | 클릭, 마우스 등 | OnLButtonDown() |
CPaintDC | WM_PAINT 시 클리핑 영역만 그림 (효율적) | 화면 갱신 시 | OnPaint() |
아래는 MFC 기반의 간단한 실행 가능한 프로젝트 예제입니다. CWindowDC, CClientDC, CPaintDC를 각각 사용하는 코드가 포함된 단일 창 애플리케이션(MFC Application) 으로 구성되어 있습니다.
3. 프로젝트 구성
- 프로젝트명: SimpleDCExample
- MFC 타입: Single Document Interface (SDI)
- Visual Studio → MFC App 선택 → 기본 설정으로 생성
4. 코드 추가 (예제 구현)
1. SimpleDCExampleView.cpp 수정
#include "pch.h"
#include "framework.h"
#include "SimpleDCExample.h"
#include "SimpleDCExampleDoc.h"
#include "SimpleDCExampleView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CSimpleDCExampleView, CView)
BEGIN_MESSAGE_MAP(CSimpleDCExampleView, CView)
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
END_MESSAGE_MAP()
// 👉 초기 그림 테스트용
void CSimpleDCExampleView::OnDraw(CDC* pDC)
{
pDC->TextOutW(10, 10, L"OnDraw에서 출력됩니다.");
}
// 👉 전체 윈도우를 대상으로 그림
void CSimpleDCExampleView::OnLButtonDown(UINT nFlags, CPoint point)
{
// 전체 윈도우 DC (캡션바 포함)
CWindowDC dc(this);
dc.SelectStockObject(DC_PEN);
dc.Rectangle(0, 0, 200, 200);
// 클라이언트 영역만
CClientDC clientDC(this);
clientDC.TextOutW(point.x, point.y, L"클릭됨!");
CView::OnLButtonDown(nFlags, point);
}
// 👉 WM_PAINT 메시지로 들어올 때 처리
void CSimpleDCExampleView::OnPaint()
{
CPaintDC dc(this); // 자동으로 BeginPaint / EndPaint 처리
dc.TextOutW(10, 40, L"WM_PAINT 메시지 처리 중");
}
2. SimpleDCExampleView.h 확인
class CSimpleDCExampleView : public CView
{
protected: // serialization에서만 만들어집니다.
CSimpleDCExampleView() noexcept;
DECLARE_DYNCREATE(CSimpleDCExampleView)
public:
virtual void OnDraw(CDC* pDC); // 이 뷰를 그리기 위해 오버라이드됩니다.
virtual void OnPaint(); // WM_PAINT 처리용
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // 마우스 클릭 처리
protected:
DECLARE_MESSAGE_MAP()
};
5. 실행 방법
- Visual Studio에서 SimpleDCExample 생성
- 위 코드를 SimpleDCExampleView.cpp / .h에 반영
- 빌드 후 실행
- 창 클릭 시:
- 전체 윈도우 테두리에 사각형 표시
- 마우스 위치에 "클릭됨!" 출력
- 창 리사이즈 또는 최소화/복원 시:
- OnPaint에서 "WM_PAINT 메시지 처리 중" 출력
반응형