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

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

 

반응형