[MFC 9.0] CDialogEx를 아세요?
1. 개요
CDialog를 사용해보신 분이라면 기본적으로 그려지는 회색의 배경색에 너무나 익숙하실 겁니다.
MFC 9.0에서는 CDialogEx라는 CDialog를 상속받은 클래스가 추가 되었고,
CDialogEx가 제공하는 SetBackgroundColor(), SetBackgroundImage()를 이용하여
너무도 익숙한 회색의 배경색을 보다 손쉽게 바꾸는 방법을 알아봅니다.
2. 기존의 CDialog에서 배경색을 바꾸는 방법
이때까지 CDialog의 배경색을 바꾸지 못한 것은 아닙니다.
가장 널리 쓰는 방법이 아마도 OnPaint 함수에서 전체적으로 그려버리는(?) 방법일 것입니다.
아마도 OnPaint에서 그리는 방법은 배경색을 바꾼다기보다는 특정 스킨을 쒸우는 형태가 일반적이었습니다.
배경색을 바꾸기 위해 가장 간단한 방법은 EraseBkgnd 메세지를 핸들링하는 방법이 아닐까 생각이 드는군요.
BOOL CDialogTestDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rc;
GetClientRect(rc);
pDC->FillSolidRect(rc, RGB(255,255,255));return TRUE;
// return CDialog::OnEraseBkgnd(pDC);
}
기존에 불리는 CDialog::OnEraseBkgrnd() 함수 대신에 배경색을 바꿀 클라이언트의 영역을 구해와서
파라미터로 넘어온 CDC를 가지고 원하는 색으로 칠하는 방식입니다.
그러나 Dialog에 컨트롤을 삽입했다면 아래와 같은 형태로 보일 겁니다.
각 컨트롤의 배경색이 회색이라서 아주 어색한 화면이 되어버렸네요.
그래서 각 컨트롤의 배경색을 투명으로 바꾸어주기 위해서 CtlColor 메시지를 또 핸들링하는 함수를 만들어야 합니다.
OnCltColor 메세지 핸들러에서 컨트롤의 글씨 부분과 배경색을 투명으로 바꾸어 주기 위해
pDC->SetBkMode(TRANSPARENT) 같이 배경을 투명으로 변경하고 NULL_BRUSH 브러시를 반환하게 됩니다.
(구체적인 코드는 아래에서 알아보겠습니다.)
모든 창에 저런식의 코드를 일일히 작성해주어야 했습니다.
그래서 아마도 CDialogEx라는 간단하지만 편리한 Class를 추가하게 된 것이겠지요.
3. CDialogEx를 사용하여 배경색을 바꾸는 방법
CDialogEx 에는 아래와 같은 배경색을 바꾸는 메소드가 있습니다.
void SetBackgroundColor(COLORREF color, BOOL bRepaint = TRUE);
단지 OnInitDialog 부분에서 SetBackgroundColor(RGB(255,255,255)); 를 호출하므로써 배경색을 바꿀수 있게되었습니다.
afxdialogex.cpp 를 살펴보면
HBRUSH CDialogEx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (m_brBkgr.GetSafeHandle() != NULL || m_hBkgrBitmap != NULL)
{
#define MAX_CLASS_NAME 255
#define STATIC_CLASS _T("Static")
#define BUTTON_CLASS _T("Button")if (nCtlColor == CTLCOLOR_STATIC)
{
TCHAR lpszClassName [MAX_CLASS_NAME + 1];::GetClassName(pWnd->GetSafeHwnd(), lpszClassName, MAX_CLASS_NAME);
CString strClass = lpszClassName;if (strClass == STATIC_CLASS)
{
pDC->SetBkMode(TRANSPARENT);
return(HBRUSH) ::GetStockObject(HOLLOW_BRUSH);
}if (strClass == BUTTON_CLASS)
{
// if ((pWnd->GetStyle() & BS_GROUPBOX) == 0)
{
pDC->SetBkMode(TRANSPARENT);
}return(HBRUSH) ::GetStockObject(HOLLOW_BRUSH);
}
}
}return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}
이미 OnCtrColor 함수를 위와같이 구현해 놓은 것을 알 수 있습니다.
만약 MFC 9.0을 쓰지 못할 경우 CDialog를 상속받고 위와 같은 코드를 추가하시면 원하는 배경색으로 변경할 수 있겠습니다.
참고로 여기서 ::GetStockObject(HOLLOW_BRUSH) 부분이 있는데 HOLLOW_BRUSH의 정의를 보면 NULL_BRUSH랑 같다는 것을 알 수 있습니다.
in WinGDI.h
#define NULL_BRUSH 5
#define HOLLOW_BRUSH NULL_BRUSH
4. 배경색이 아닌 배경이미지 사용하기
CDialogEx 에는 아래와 같이 두개 방식의 배경을 그릴 수 있는 함수가 있습니다.
void SetBackgroundImage(HBITMAP hBitmap, BackgroundLocation location = BACKGR_TILE,
BOOL bAutoDestroy = TRUE, BOOL bRepaint = TRUE);
BOOL SetBackgroundImage(UINT uiBmpResId, BackgroundLocation location = BACKGR_TILE, BOOL bRepaint = TRUE);
Bitmap File을 Resource에 추가하시고 OnInitDialog 함수에
SetBackgroundImage(IDB_BG, CDialogEx::BACKGR_TOPRIGHT);
위와 같이 추가하시면 아주 손쉽게 배경 이미지를 삽입할 수 있습니다.
첫번째 파라미터가 Resource 에 추가한 Resource Id 이구요.
두번째 파라미터는 그 비트맵 이미지를 어떤 위치에 그려줄지를 지정하는 것으로서 총 5가지가 존재합니다.
enum BackgroundLocation
{
BACKGR_TILE, // 타일 방식으로
BACKGR_TOPLEFT, // 왼쪽 상단
BACKGR_TOPRIGHT, //오른쪽 상단
BACKGR_BOTTOMLEFT, // 왼쪽 하단
BACKGR_BOTTOMRIGHT, // 오른쪽 하단
};
타일 방식은 이미지가 창 크기에 맞게 중복해서 채워지는 것이구요.
나머지는 각각의 위치에 이미지를 그리고 이미지 크기가 창의 크기보다 작을 때에는
SetBackgroundColor에 의해서 지정된 배경색이 칠해지게 됩니다.
아주 쉽죠?
5. 아쉬운 점 한가지
CheckBox 컨트롤인 경우 XP에서 글자의 색과 배경색이 바뀌지 않는 버그가 있는데요.
http://www.codeguru.com/forum/archive/index.php/t-333314.html 이곳을 참고하시면 되겠습니다.
CDialogEx에서 배경색을 바꾸고 체크 박스 컨트롤을 사용하시면
[그림 4. CheckBox Control XP Theme 버그]
위와 같이 검은색으로 표시되는 것을 알 수 있습니다.
위는 XP Theme 와 관련된 사항으로 SetWindowTheme( [CheckBoxControl Handle] , L"", L""); 을 사용하는 방법도 있긴 하겠습니다만
좀 아쉬운 부분입니다.
(SetWindowTheme 함수를 사용하시려면 프로젝트 속성에서 Linker Input 부분에 UxTheme.lib 라이브러리를 추가시켜야 합니다.)
6. 샘플 프로젝트
chaoskcuf's lab
"프로그래밍 / TIP& Study" 분류의 다른 글
| [퀴즈] SQLite collate 문제 (0) | 2010/07/16 |
| [TIP] XP, Vista에서 CD/DVD롬이 보이지 않을 경우 (1) | 2009/08/05 |
| [C#] WinForm 에서 Docking 순서 변경하기 (0) | 2009/07/29 |
| [WPF] InkCanvas 사용하기 (0) | 2009/06/29 |
| [C#] Control Library 만들 때 TIP (0) | 2009/06/26 |
| [C#] 자연스럽게 Pen으로 그리기 (0) | 2009/06/23 |
| [WPF] Canvas의 Width, Height Binding (0) | 2009/06/23 |
| [C#] DateTime으로 7일 후는 어떻게? (0) | 2009/06/23 |
트랙백 주소 : http://chaoskcuf.com/trackback/128
-
Percocet.
tracked from Percocet.
2011/02/14 20:53
삭제
Percocet.
-
Cla.
tracked from Cla.
2011/02/25 04:29
삭제
Cla.
-
Adderall adults calm.
tracked from Adderall adults calm.
2011/02/25 15:29
삭제
Adderall adults calm.
-
Ultram vs ultracet.
tracked from Ultram vs ultracet.
2011/02/26 02:03
삭제
Ultracet vs ultram. Ultram vs ultracet.
-
Buy.
tracked from Buy.
2011/03/12 12:20
삭제
Buy.



DialogTest.zip
댓글을 달아 주세요
molla...
ㄷㄷㄷ 스팸인줄 알았어요..;;;
CheckBox text가 검정색으로 나와서 인터넷 검색하다가 이 홈페이지까지 왔네요 ^^ 좋은정보 감사합니다
덕분에 버그를 해결했어요~
그런데....
체크를 누르면 텍스트가 굵은 글씨로 변해 버리는 버그가 생겨서 이부분은 아직 해결 못하고 있네요
ㅠ_ㅠ
혹시 아시면 guyguy007@naver.com 으로 연락좀 주세요