성엽이
KKIMSSI
성엽이
전체 방문자
오늘
어제
  • 분류 전체보기 (454)
    • :) (2)
    • C프로그래밍이론 (9)
    • C++프로그래밍 (64)
      • STL (1)
    • C# (2)
    • Visual studio 10.0 (9)
    • AT91SAM7S256 (21)
    • 논리회로 (14)
    • AVR2560 (11)
    • TCPIP (16)
    • NetWork (4)
      • Ubuntu Linux (2)
    • Assembly (21)
    • UNIX 프로그래밍 (6)
    • RFID 분석 (1)
    • Win32 API (7)
    • Cortex-M3 (4)
    • Unity (91)
    • Flutter (9)
    • OwnProject (11)
      • It's mine (5)
      • 마인드스톰 실습 (1)
      • 보고서 자료 (2)
      • RPi B+ (2)
    • ETC (25)
      • 상식 (3)
    • MFC (40)
    • PostgeSQL (18)
    • 영상제어 (6)
      • VFW_영상처리 (1)
    • Python (0)
    • Java (30)
      • SpringBoot (2)
      • Javascript (1)
      • JSP (13)
      • Spring (8)
    • Oracle (4)
      • SQL (3)
    • HTML (6)
      • Thymeleaf (1)
      • CSS (1)
      • Bootstrap (3)
    • IDE (1)
      • VS Code (1)
    • Android (2)
    • Privacy Policy (0)
    • MYSQL (2)
      • MariaDB (2)
    • AWS (5)
    • 개인공부 (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록
  • 관리자
  • 글쓰기

공지사항

인기 글

태그

  • WINAPI
  • 문자열 나누기
  • Boot Code 분석
  • ARM Reverse Engineering
  • MFC

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
성엽이

KKIMSSI

MFC

[MFC/스크랩] MFC 에서 DC 클래스 얻기 및 내부 구조 / CDC, CPaintDC, CClientDC, CWindowDC 사용법

2014. 1. 21. 16:04

윈도우 화면으로 글씨나 그래픽을 출력하기 위해서는 반드시 해당 윈도우의 DC를 얻어와야 한다.

Win32 API 프로그램을 만들 때는 GetDC(), ReleaseDC() 함수를 통해서 DC를 얻고 사용하는데,

MFC는 이 함수를 포함하는 CClientDC 클래스를 제공한다. 또한 WM_PAINT에 대응하는 함수로

BeginPaint(), EndPaint() 함수가 존재하는데, 이 함수를 포함하는 CPaintDC 클래스도 제공된다.

보통 마우스를 화면에 클릭할 때 사각형을 그리려면 다음과 같이 코딩한다.

 

Win32 API 에서

case WM_LBUTTONDOWN :

     {

         CPoint point( (DWORD)lParam );        // CPoint는 MFC 클래스
         HDC hdc = GetDC( this->m_hWnd );
         Rectangle( hdc, point.x, point.y, point.x+50, point.y+50 );
         ReleaseDC( this->m_hWnd, hdc );
     }

 

 

 

MFC 에서

void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
    CClientDC dc( this );      // 생성자에서 GetDC() 함수를 호출하여 DC 생성
    dc.Rectangle( point.x, point.y, point.x+50, point.y+50 );
   
    CView::OnLButtonDown(nFlags, point);

    // CClientDC 소멸자에서 ReleaseDC() 자동 호출
}


또는 다음과 같이 CDC 클래스를 사용해서 구현할 수도 있다.

 

void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
      CDC* pDC = GetDC();
      pDC->Rectangle( point.x, point.y, point.x+50, point.y+50 );
      ReleaseDC( pDC );


      CView::OnLButtonDown(nFlags, point);

 

 }


 

 

 

 

다음은 MFC에서 API 함수를 직접 사용하는 경우이다.

 

 

 

void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
      HDC hdc = ::GetDC( this->m_hWnd );
      ::Rectangle( hdc, point.x, point.y, point.x+50, point.y+50 );
      ::ReleaseDC( this->m_hWnd, hdc );

   
      CView::OnLButtonDown(nFlags, point);

 }

 

 

CDC 클래스

CDC 클래스는 GDI와 관련된 모든 함수들을 갖고 있다.

class CDC : public CObject

{

       DECLARE_DYNCREATE(CDC)

public:

 

// Attributes

       HDC m_hDC;           // The output DC (must be first data member)

       HDC m_hAttribDC;    // The Attribute DC

       ...

   

// Type-safe selection helpers

public:

       virtual CGdiObject* SelectStockObject(int nIndex);

       CPen* SelectObject(CPen* pPen);

       CBrush* SelectObject(CBrush* pBrush);

       ...

 

       CPoint MoveTo(int x, int y);

       CPoint MoveTo(POINT point);

       BOOL LineTo(int x, int y);

       BOOL LineTo(POINT point);

       ...

};

 

                                                                                                                                    

 

CClientDC 클래스

CClientDC 클래스는 WM_PAINT 메시지가 발생하지 않을 때 화면에 그림을 그리기 위해

사용한다. 이 클래스는 내부적으로 GetDC(), ReleaseDC() 함수를 사용해서 구현되어 있다.

 

class CClientDC : public CDC

{

       DECLARE_DYNAMIC(CClientDC)

 

// Constructors

public:

       CClientDC(CWnd* pWnd);

 

// Attributes

protected:

        HWND m_hWnd;

 

// Implementation

public:

        virtual ~CClientDC();

};

 

다음은 CClientDC의 생성자와 소멸자이다. 내부 코드를 보면 GetDC(), ReleaseDC() 함수를

사용하여 구현되어 있음을 알 수 있다.

 

CClientDC::CClientDC(CWnd* pWnd)

{

       ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));

 

       if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))

                AfxThrowResourceException();

}

 

CClientDC::~CClientDC()

{

       ASSERT(m_hDC != NULL);

       ::ReleaseDC(m_hWnd, Detach());

}

 

                                                                                                                                   

 

CWindowDC 클래스

CWindowDC는 타이틀바, 메뉴바, 상태바 등을 포함하는 전체 윈도우에 대한 DC를 얻기 위해 사용한다.

예를 들어 다음과 같이 하면, 타이틀바에 사각형을 그릴 수 있다.

 

void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{

 

     CWindowDC wdc( AfxGetMainWnd() );
     wdc.Rectangle( 0, 0, 20, 20 );

    

 


      CView::OnLButtonDown(nFlags, point);

 }

다음은 MFC가 내부적으로 사용하는 CWindowDC의 클래스 선언이다.

class CWindowDC : public CDC

{

       DECLARE_DYNAMIC(CWindowDC)

 

// Constructors

public:

       CWindowDC(CWnd* pWnd);

 

// Attributes

protected:

       HWND m_hWnd;

 

// Implementation

public:

       virtual ~CWindowDC();

};

 

                                                                                                                                   

 

CPaintDC 클래스

 

CPaintDC 클래스는 WM_PAINT 메시지를 처리하는 클래스이며,

BeginPaint() 함수와 EndPaint() 함수로 이루어 진다. MFC의 뷰 클래스는

WM_PAINT 메시지를 받으면 내부적으로 CPaintDC 클래스를 생성하고,

OnDraw() 함수를 호출해 준다. 그래서 OnDraw() 함수를 WM_PAINT처럼

처리하는 것이다.

void CView::OnPaint()             // WM_PAINT에 의해 호출된다.
{
      // standard paint routine
      CPaintDC dc(this);
      OnPrepareDC(&dc);            // 프린트를 먼저 부른다.
      OnDraw(&dc);                    // 화면을 다시 그리는 OnDraw()를 부른다.
}

void CTestView::OnDraw(CDC* pDC)
{
      CTestDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);

}

 

 

다음은 CPaintDC의 생성자와 소멸자이다. 내부 코드를 보면 BeginPaint(), EndPaint() 함수를

사용하여 구현되어 있음을 알 수 있다.

 

CPaintDC::CPaintDC(CWnd* pWnd)

{

       ASSERT_VALID(pWnd);

       ASSERT(::IsWindow(pWnd->m_hWnd));

 

       if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))

                AfxThrowResourceException();

}

 

CPaintDC::~CPaintDC()

{

       ASSERT(m_hDC != NULL);

       ASSERT(::IsWindow(m_hWnd));

 

       ::EndPaint(m_hWnd, &m_ps);

       Detach();

}

 

                                                                                                                                   

 

 

[ CDC ]

    |

     ---> [ CClientDC ]

    |

     ---> [ CPaintDC ]

    |

     ---> [ CWindowDC ]

1. CDC

    반드시 ReleaseDC()함수와 쌍을 이루어야 한다.

    CDC * pDC = GetDC();

    ...

    ReleaseDC(pDC);

* OnDraw()함수의 인자로 받는 CDC는 ReleaseDC()를 사용하지 않음에 주의

2. CClientDC

    화면을 출력하는 현재 클래스 어느 곳에서든지 설정하면 바로 현재 화면을 얻을 수 있다.

    CClientDC cdc(this);

3. CPaintDC

    OnPaint 함수내에서만 사용.

4. CWindowDC

    윈도 영역 전체를 받는 DC

    CWindowDC * pDC = GetWindowDC();

    ...

    ReleaseDC(pDC);

참고) 그래픽객체와 SelectObject & DeleteObject

    // 그래픽 객체 생성

    CPen pen, * oldpen;

    pen.CreatePen(PS_SOLID, 1, RGB(0,0,0);

    // 객체를 DC에 등록

    oldpen = pDC->SelectObject(&pen);

    // 출력

    pDC->Rectangle(0,0,100,100);

    // 이전 객체로 되돌림

    pDC->SelectObject(oldpen);

    // 객체 삭제

    pen.DeleteObject();

 

5. HDC , CDC 값 구하기

 

HDC hdc = ::GetDC(hWnd);

CDC *pDC = CDC::FromHandle(hdc);

 

긁어온(?) 사이트 : http://wooya510.egloos.com/942330

Visual C++ : http://wooya510.egloos.com/category/Visual%20C%2B%2B

저작자표시 (새창열림)

'MFC' 카테고리의 다른 글

[MFC] 모달 vs 모달리스  (0) 2014.02.04
[MFC] MFC Control (도구상자, 컨트롤) 함수 모음 정리  (0) 2014.01.29
[MFC] 2014.01.24 더블콜론(Scope resolution operator), " :: " 을 쓰는 이유  (2) 2014.01.24
[MFC] MFC 프린터 관련 함수  (0) 2014.01.22
[MFC/bitmap파일 출력하기]  (2) 2014.01.21
    'MFC' 카테고리의 다른 글
    • [MFC] MFC Control (도구상자, 컨트롤) 함수 모음 정리
    • [MFC] 2014.01.24 더블콜론(Scope resolution operator), " :: " 을 쓰는 이유
    • [MFC] MFC 프린터 관련 함수
    • [MFC/bitmap파일 출력하기]
    성엽이
    성엽이

    티스토리툴바