에디트에 대한 기초강좌를 마무리한 시점에서 질문이 하나 들어왔다.. 지금까지의 내용을 기초로 에디트의 전체 배경을 바꾸었는데.. 깜빡이거나 먼가 이상하다...??
지난 강좌를 찾아보니, 에디트에 대한 배경 처리가 제대로 마무리 되지 못한 상태에서 강좌를 마쳐 혼란을 가져온것일 수 있을꺼 같아.. 질문을 토대로 배경처리 기능을 마무리 하려고 한다.
위 그림은 두가지로 그 기능이 분류된다.
1. 왼쪽 에디트 -> 글자 바탕과 배경색상을 모두 녹색으로 처리한 것 2. 오른쪽 에디트 -> 글자 바탕은 TRANSPARENT 시키고, 바탕에는 HATCH 브러쉬를 뿌린것이다.
위 두가지 구현에는 다음과 같은 차이가 있다. 1번은 글자와 배경을 모두 그려주므로, 글씨를 쓸때 잔상이 남거나 깜빡임이 전혀없다. 2번은 글자는 쓰되 배경을 그려주지 않으므로 글씨를 쓸때 깜빡임은 없으나 잔상이 남는다. 이러한 이유로 두가지의 구현 부분에 조금 차이를 가지게 된다.
기본적인 코드는 브러쉬를 2개 만든다는 점만 빼고는 헤더에 추가할 내용은 없다. BOOLCSssDlg::OnInitDialog() { CDialog::OnInitDialog();
// 클래스 위저드에서 WM_CTLCOLOR 이벤트 핸들러를 추가한다. HBRUSHCSssDlg::OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor) { HBRUSHhbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
switch(nCtlColor) { caseCTLCOLOR_EDIT: pDC->SetTextColor(RGB(255,0,0)); if(pWnd->GetDlgCtrlID()==IDC_EDIT1) { // 글자 바탕을 녹색으로 하고, 녹색 솔리드 브러쉬를 리턴한다. // 이게 전부다. pDC->SetBkColor(RGB(0,255,0)); returnm_brush1; } elseif(pWnd->GetDlgCtrlID()==IDC_EDIT2) { // 글자의 배경을 그려주게 되면 바탕의 해치브러쉬 영역에 글자뒷 부분은 // 녹색 사각형이 그려지게 된다. // 이를 막아주기 위하여, 배경그리는 기능을 제거한다. TRANSPARENT pDC->SetBkMode(TRANSPARENT);
// 에디트 컨트롤 영역을 구한 후에 // 브러쉬로 색칠해준다. CRectrc; GetDlgItem(IDC_EDIT2)->GetWindowRect(rc); ScreenToClient(rc); pDC->FillRect(rc,&m_brush2);
returnm_brush2; } } returnhbr; }
클래스위저드에서 IDC_EDIT2의 EN_CHANGE 이벤트 핸들러를 추가한다. 이 핸들러를 추가하는 이유는 두번째 에디트는 글자의 배경이 뒤에 그려지는 해치 브러쉬의 패턴을 덥어쓰는 걸 막아주기 위하여 TRANSPARENT 속성을 주었으므로, 글씨의 뒷부분을 그려주지 않게된다. 그러므로 잔상이 남게되어 글자에 대한 변경이 발생하면 배경을 다시 그려주도록 하기 위해서이다. void CSssDlg::OnChangeEdit2() { CRect rc; GetDlgItem(IDC_EDIT2)->GetWindowRect(rc); ScreenToClient(rc); InvalidateRect(rc); }
switch(nCtlColor) { case CTLCOLOR_STATIC: { pDC->SetTextColor(RGB(255, 0, 0));
if(pWnd->GetDlgCtrlID() == IDC_STATIC_1) pDC->SetBkColor(RGB(0, 255, 0)); else if(pWnd->GetDlgCtrlID() == IDC_STATIC_3) // 앙? 그냥 브러쉬를 리턴하면 끝이냐? // 그렇다 그냥은 디폴트 브러쉬가 날라가게 되는데.. // 여기에 먼가 특별한 브러쉬를 만들어 리턴하면 그게 그 컨트롤의 // 배경에 영향을 미치게 된다. // 다양한 브러쉬를 만들어 리턴해보자 ^^; return m_brush; else if(pWnd->GetDlgCtrlID() == IDC_STATIC_2) { pDC->SetBkColor(RGB(0, 255, 0)); return m_brush; } } } // TODO: Return a different brush if the default is not desired return hbr;
}
--------------------------------------------------------------------------------- 이 부분을 진행하다 보니, 만약 패턴 브러쉬를 넣었을 경우는 어떻게 될까? 라는 생각이 들어서 별도로 진행해 보았다.
이 그림은 위의 소스 일부를 수정하여, 변경해 본 것으로.. Hatch 브러쉬를 이용하여 배경을 칠해본것이다. 자? 두번째를 어떻게 처리할 수 있을까?
BOOL CSssDlg::OnInitDialog() { CDialog::OnInitDialog(); m_brush.CreateHatchBrush(HS_DIAGCROSS, RGB(0, 255, 0)); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
switch(nCtlColor) { case CTLCOLOR_STATIC: { pDC->SetTextColor(RGB(255, 0, 0)); pDC->SetBkColor(RGB(0, 255, 0)); } } // TODO: Return a different brush if the default is not desired return hbr;
}
위와 같이 설정하면 모든 스태틱 컨트롤에 영향을 준다. 실행 결과 화면은 다음과 같다.
필요한 컨트롤만 색상을 변경하려면 다음과 같은 추가 작업이 필요하다. 좌측 상단의 첫번째 컨트롤의 속성창을 열어서 아이디를 IDC_STATIC_1 이라고 변경한다. 그리고 다음과 같이 코드를 변경한다.
switch(nCtlColor) { case CTLCOLOR_STATIC: { if(pWnd->GetDlgCtrlID() == IDC_STATIC_1) { pDC->SetTextColor(RGB(255, 0, 0)); pDC->SetBkColor(RGB(0, 255, 0)); } } } // TODO: Return a different brush if the default is not desired return hbr; }
저번에 이어 에디트 컨트롤을 사용하면서 글자색이나 배경색을 바꾸는 것에 대하여 알아보자. 이 기능은 에디트 컨트롤 뿐만 아니라, 거의 모든 문자열 입출력이 있는 컨트롤에 해당하는 기능이므로 잘 알아두면 다른 컨트롤에서도 쉽게 사용할 수 있다.
다이알로그의 이벤트 중에 WM_CTLCOLOR 라는 이벤트가 있습니다.
저걸 추가하고 나면 화면상에 다음과 같은 코드가 자동으로 추가됩니다.
HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Return a different brush if the default is not desired
return hbr;
}
1. CDC* pDC - MFC에서 제공하는 디바이스 컨텍스트
2. CWnd* pWnd - 대상이 되는 다이알로그에 올려진 컨트롤 윈도우
3. UINT nCtlColor - 대상이 되는 컨트롤의 구분 타입.
3번의 대상이 되는 컨트롤의 구분 타입은 다음과 같습니다.
이는 winuser.h에 선언되어 있구요.
#define CTLCOLOR_MSGBOX 0
#define CTLCOLOR_EDIT 1
#define CTLCOLOR_LISTBOX 2
#define CTLCOLOR_BTN 3
#define CTLCOLOR_DLG 4
#define CTLCOLOR_SCROLLBAR 5
#define CTLCOLOR_STATIC 6
나는 에디트 컨트롤을 대상으로 작업을 하므로 CTLCOLOR_EDIT 를 사용할 것입니다.
그럼 다음과 같은 코드를 추가해 봅니다.
HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
switch(nCtlColor)
{
case CTLCOLOR_EDIT:
{
if(pWnd->GetDlgCtrlID() == IDC_EDIT9)
pDC->SetTextColor(RGB(255, 0, 0));
else if(pWnd->GetDlgCtrlID() == IDC_EDIT14)
pDC->SetBkColor(RGB(0, 255, 0));
}
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
의미를 해석해보면 IDC_EDIT9번을 가진 에디트 컨트롤의 글자색을 빨간색 RGB(255,0,0))으로
IDC_EDIT14번을 가진 에디트 컨트롤의 글자 배경색을 녹색 RGB(0,255,0)으로 바꿔라 입니다.
여러개를 한꺼번에 바꾸거나, 그런건 머 위의 코드를 약간 수정하면 될테니 그건 손수 한번 해보세요.