본문 바로가기

Windows/MFC

[ MFC ] CDC와 DC 클래스 사용하기

반응형

 

 

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. 실행 방법

  1. Visual Studio에서 SimpleDCExample 생성
  2. 위 코드를 SimpleDCExampleView.cpp / .h에 반영
  3. 빌드 후 실행
  4. 창 클릭 시:
    • 전체 윈도우 테두리에 사각형 표시
    • 마우스 위치에 "클릭됨!" 출력
  5. 창 리사이즈 또는 최소화/복원 시:
    • OnPaint에서 "WM_PAINT 메시지 처리 중" 출력

 

반응형