2008년 03월 12일
Custom Control
한 기능을 수행해야 하는 콘트롤의 집합이 있을때, 이 집합을 묶어서 하나의 콘트롤로 만들고 싶다는 생각을 해본적이 있는가?
기존의 콘트롤의 모양이나 행동 방식을 변형하고 싶을때, 나만의 방식으로 동작하는 콘트롤을 만들고 싶다고 생각해본적이 잇는가?
이럴때 사용자 정의 콘트롤을 만드는거다.
Custom Control 고고싱~
1. 자신이 원하는 Base Class 로부터(예를들어, CWnd) 상속받아 클래스를 만든다.
2. WM_PAINT, WM_ERASEBKGND 메세지 함수를 정의하고 PreSubclassWindow 함수를 오버라이드 한다.
(PreSubclassWindow 함수를 재정의 할지는 선택사항이나, 콘트롤 초기화 루틴으로 쓰기엔 적당하다)
=> 지금 진행중에 알게 된 사실인데 만약 CWnd 에서 상속받은 클래스르를 CMyCtrl 이라 하고,
멤버로 몇가지 콘트롤(CEdit, CButton 등)을 가지고 있을때
이곳의 PreSubclassWindow 에서 이 멤버 콘트롤들을 초기화 하면 안된다.
=> 그래서, 멤버 콘트롤을 초기화 시키기 위하여 Create 함수를 만들고 그 안에서 CWnd::Create() 를 호출하여
이것이 완료 된 다음에 멤버 콘트롤에 대하여 Create() 함수를 호출하였다.
=> 자신의 콘트롤에 멤버로 몇가지 콘트롤(CEdit, CButton 등)을 가지고 있다면 OnPaint 나 OnEraseBkGnd 를 재정의
하지 않는게 좋은거 같다.
3. 추가한 메세지 함수의 내부를 구현한다.
OnPaint, OnEraseBkgnd : 이 함수 내부에서 이 윈도우가 어떻게 보여줄지를 그려주면 된다.
4. 이 클래스를 사용하기 위해 외부에서 CWnd::Create() 함수를 이용한다.
이 방법은 이 콘트롤을 동적으로 추가 할때 사용하면 될 것이다.
5. 만약, VC의 리소스 편집기에서 편집하고 싶다면(정적콘트롤추가) 다음과 같이 하면 된다.
5-1. 콘트롤의 생성자에서 아래 함수를 호출한다. (윈도우 클래스를 등록해준다.)
#define MYCUSTOMCTRL_CLASSNAME _T("NlyRangeCtrl") // Window class name
BOOL MyCustomCtrl::RegisterWindowClass()
{
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
if (!(::GetClassInfo(hInst, MYCUSTOMCTRL_CLASSNAME, &wndcls)))
{
// otherwise we need to register a new class
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 = MYCUSTOMCTRL_CLASSNAME;
if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
return FALSE;
}
}
return TRUE;
}
5-2. Create 함수를 재정의 한다.
BOOL MyCustomCtrl::Create(CWnd* pParentWnd, const RECT& rect, UINT nID, DWORD dwStyle/*=WS_VISIBLE*/)
{
return CWnd::Create(NLYRANGECTRL_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID);
}
5-3. 자 이제 리소스 편집기에서 Custom Control 리소스를 추가하고 그 속성의 Class Name 에
내가 정의한 클래스 이름을 넣어 준다. ( MYCUSTOMCTRL_CLASSNAME )
5-4. DoDataExchange 에 Custom Control 과 나의 변수를 맵핑 시켜준다.
DDX_Control(pDX, IDC_CUSTOM1, m_MyControl);
6. 이제 내 맘대로 내 콘트롤을 만들어 쓰자.
보다 자세한 내용은 이곳을 참고하자.
기존의 콘트롤의 모양이나 행동 방식을 변형하고 싶을때, 나만의 방식으로 동작하는 콘트롤을 만들고 싶다고 생각해본적이 잇는가?
이럴때 사용자 정의 콘트롤을 만드는거다.
Custom Control 고고싱~
1. 자신이 원하는 Base Class 로부터(예를들어, CWnd) 상속받아 클래스를 만든다.
2. WM_PAINT, WM_ERASEBKGND 메세지 함수를 정의하고 PreSubclassWindow 함수를 오버라이드 한다.
(PreSubclassWindow 함수를 재정의 할지는 선택사항이나, 콘트롤 초기화 루틴으로 쓰기엔 적당하다)
=> 지금 진행중에 알게 된 사실인데 만약 CWnd 에서 상속받은 클래스르를 CMyCtrl 이라 하고,
멤버로 몇가지 콘트롤(CEdit, CButton 등)을 가지고 있을때
이곳의 PreSubclassWindow 에서 이 멤버 콘트롤들을 초기화 하면 안된다.
=> 그래서, 멤버 콘트롤을 초기화 시키기 위하여 Create 함수를 만들고 그 안에서 CWnd::Create() 를 호출하여
이것이 완료 된 다음에 멤버 콘트롤에 대하여 Create() 함수를 호출하였다.
=> 자신의 콘트롤에 멤버로 몇가지 콘트롤(CEdit, CButton 등)을 가지고 있다면 OnPaint 나 OnEraseBkGnd 를 재정의
하지 않는게 좋은거 같다.
3. 추가한 메세지 함수의 내부를 구현한다.
OnPaint, OnEraseBkgnd : 이 함수 내부에서 이 윈도우가 어떻게 보여줄지를 그려주면 된다.
4. 이 클래스를 사용하기 위해 외부에서 CWnd::Create() 함수를 이용한다.
이 방법은 이 콘트롤을 동적으로 추가 할때 사용하면 될 것이다.
5. 만약, VC의 리소스 편집기에서 편집하고 싶다면(정적콘트롤추가) 다음과 같이 하면 된다.
5-1. 콘트롤의 생성자에서 아래 함수를 호출한다. (윈도우 클래스를 등록해준다.)
#define MYCUSTOMCTRL_CLASSNAME _T("NlyRangeCtrl") // Window class name
BOOL MyCustomCtrl::RegisterWindowClass()
{
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
if (!(::GetClassInfo(hInst, MYCUSTOMCTRL_CLASSNAME, &wndcls)))
{
// otherwise we need to register a new class
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 = MYCUSTOMCTRL_CLASSNAME;
if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
return FALSE;
}
}
return TRUE;
}
5-2. Create 함수를 재정의 한다.
BOOL MyCustomCtrl::Create(CWnd* pParentWnd, const RECT& rect, UINT nID, DWORD dwStyle/*=WS_VISIBLE*/)
{
return CWnd::Create(NLYRANGECTRL_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID);
}
5-3. 자 이제 리소스 편집기에서 Custom Control 리소스를 추가하고 그 속성의 Class Name 에
내가 정의한 클래스 이름을 넣어 준다. ( MYCUSTOMCTRL_CLASSNAME )
5-4. DoDataExchange 에 Custom Control 과 나의 변수를 맵핑 시켜준다.
DDX_Control(pDX, IDC_CUSTOM1, m_MyControl);
6. 이제 내 맘대로 내 콘트롤을 만들어 쓰자.
보다 자세한 내용은 이곳을 참고하자.

# by | 2008/03/12 16:55 | VC++ 프로그래밍 | 트랙백 | 덧글(2)






☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]