MFC Custom_Control 연습

Dev.Write 2010. 1. 15. 04:37 Posted by zetz

원문 참조
http://www.codeproject.com/KB/miscctrl/customcontrol.aspx


MFC를 공부한지 꽤 되었지만 역시 모르는 것이 더 많다.
위 링크 참조하여 MFC 의 Custom_Control 을 공부해보자.
사용해 보니 꽤 편리했다.

우선 Custom Control 을 사용해 보면 다음과 같이 나온다.

우측의 속성 중 "Class" 에 집중하자. 이 곳에 사용할 윈도우의 ClassName을 적어야 한다.

단, 단순 클래스이름이 아닌 RegisterClass 함수로 등록한 이름임을 명심하자. 그리고 MFC 기반의 CWnd 를 상속 받은 윈도우여 한다.

 

이제 실제로 Custom Control 를 사용하기 위한 클래스를 만들어 보자.

예제는 위 링크에 있는 CBitmapView 코드이다.

클래스를 만들고,

 

헤더에 몇 가지 정의 추가하고,

BitmapView.h

#pragma once
#include "afxwin.h"

#define BITMAPVIEWER_CLASSNAME	_T("MFCBitmapViewCtrl")

class CBitmapView :
	public CWnd
{
public:
	CBitmapView(void);
	~CBitmapView(void);

	BOOL		SetBitmap(UINT nIDResource);

	DECLARE_MESSAGE_MAP()
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnPaint();

protected:
	BOOL		RegisterWindowClass();
	CBitmap		m_Bitmap;

};

 

CPP 파일에서 세부 구현 추가

BitmapView.cpp

#include "StdAfx.h"
#include "BitmapView.h"



CBitmapView::CBitmapView(void)
{
	RegisterWindowClass();
}

CBitmapView::~CBitmapView(void)
{
}

BOOL	CBitmapView::RegisterWindowClass()
{
	WNDCLASS	wndcls;
	HINSTANCE	hInst = AfxGetInstanceHandle();

	if ( !(::GetClassInfo(hInst, BITMAPVIEWER_CLASSNAME, &wndcls)) )
	{
		wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
		wndcls.lpfnWndProc      = ::DefWindowProc;
		wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
		wndcls.hInstance        = hInst;
		wndcls.hIcon            = NULL;
		wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
		wndcls.hbrBackground    = (HBRUSH) (COLOR_3DFACE + 1);
		wndcls.lpszMenuName     = NULL;
		wndcls.lpszClassName    = BITMAPVIEWER_CLASSNAME;

		if (!AfxRegisterClass(&wndcls))
		{
			AfxThrowResourceException();
			return FALSE;
		}
	}
	return TRUE;
}

BEGIN_MESSAGE_MAP(CBitmapView, CWnd)
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()	
END_MESSAGE_MAP()

BOOL CBitmapView::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	if (m_Bitmap.GetSafeHandle() != NULL)
		return TRUE;


	return CWnd::OnEraseBkgnd(pDC);
}

void CBitmapView::OnPaint()
{
	if (m_Bitmap.GetSafeHandle() != NULL)
	{
		CPaintDC dc(this);

		CDC MemDC;
		if ( !MemDC.CreateCompatibleDC(&dc) )
			return;

		CRect rt;
		GetClientRect(rt);

		BITMAP	bm;
		m_Bitmap.GetBitmap(&bm);

		CBitmap*	pOldBitmap = (CBitmap*)	MemDC.SelectObject(&m_Bitmap);
		dc.StretchBlt(0, 0, rt.Width(), rt.Height(), &MemDC,
			0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
		MemDC.SelectObject(pOldBitmap);
	}

}


BOOL	CBitmapView::SetBitmap(UINT nIDResource)
{
	return m_Bitmap.LoadBitmap(nIDResource);
}



 

이제 준비가 된 클래스를 사용하여 Custom Control 을 만들어보자.

우선 사용할 헤더파일에선 기본 센스 두 가지 해주고

#include "BitmapView.h"
...
CBitmapView           m_View;

 

CPP 파일에서 명시적으로 DDX 연결해주는 것을 잊지 말자.

DDX_Control(pDX, IDC_CUSTOM1, m_View);

 

마지막으로 아무 비트맵이나 생성해서

결과 확인

m_View.SetBitmap(IDB_BITMAP1);


결론 : 이거 잘 쓰면 편할듯?