리스트 박스의 글자색과 배경색은 기존에 해온대로 WM_CTLCOLOR 이벤트를
이용하면 아주 쉽게 해결됩니다..

HBRUSH CSssDlg::OnCtlColor(CDCpDCCWndpWndUINT nCtlColor)
{
    
HBRUSH hbr = CDialog::OnCtlColor(pDCpWndnCtlColor);

    
if(nCtlColor == CTLCOLOR_LISTBOX)
    {
        
if(pWnd->GetDlgCtrlID() == IDC_LIST1)
        {
            
pDC->SetTextColor(RGB(25500));
            
pDC->SetBkColor(RGB(255,255,0));

            
// 노랑색으로 만든 브러쉬. - m_brh.CreateSolidBrush(RGB(255,255,0));
            
return m_brh;
        }
    }
    
return hbr;
}

88.zip
0.03MB


지금까지 다룬 방식으로 아주 쉽게 처리가 되었읍니다. -_-
강좌라고 할만한 껀덕지도 없읍니다.

하지만 컨트롤을 오버라이딩해서 별도로 구현하지 않는이상.. 리스트박스는 별로
다룰만한게 없다보니.. 휴~~

이전에 이어 콤보박스가 여러개 있을 때, 각각의 콤보 색상을 어떻게 다르게 처리할 수 있는지에
대하여 진행해 보겠습니다.

우선 다이알로그에 콤보1, 콤보2 이렇게 2개를 올려놓고 진행합니다.
먼저 에디트 색상부터 변경해 보겠습니다.

[드롭다운 스타일의 콤보박스 2개를 준비합니다.]

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    
if(nCtlColor == CTLCOLOR_EDIT )
    {
        
if(pWnd->GetDlgCtrlID() == 1001)
        {
            
// 부모 윈도우가 NULL 이면 리턴한다.
            
if(pWnd->GetParent() == NULL)
                
return hbr;

            
// 부모 윈도우의 컨트롤 아이디를 구한다.
            
// 아이디가 아래와 같으면 에디트의 색상을 변경시키다.
            
switch(pWnd->GetParent()->GetDlgCtrlID())
            {
            
case IDC_COMBO1:
                
pDC->SetTextColor(RGB(0,255, 0));
                
pDC->SetBkColor(RGB(255, 0, 0));
                
break;
            
case IDC_COMBO2:
                
pDC->SetTextColor(RGB(0,0, 255));
                
pDC->SetBkColor(RGB(255, 255, 0));
                
break;
            }
        }
    }

    
return hbr;
}

결과화면...

위의 코드에서 보았듯이 콤보박스의 에디트는 부모윈도우가 콤보박스입니다.
그렇다면 리스트의 색상을 변경해 보도록 하죠...

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    
if(nCtlColor == CTLCOLOR_LISTBOX )
    {
        
if(pWnd->GetDlgCtrlID() == 1000)
        {
            
// 현재 포커스가 있는 윈도우를 구한다.
            
pWnd = pWnd->GetFocus();
            
if(pWnd && pWnd->GetParent())
            {
                
// 심플이나 드롭다운일 경우는 에디트에 포커스가 있으므로
                
// 페어런트의 컨트롤 아이디를 구한다페어런트가 콤보박스이다.
                
switch(pWnd->GetParent()->GetDlgCtrlID())
                {
                
case IDC_COMBO1:
                    
pDC->SetTextColor(RGB(0,255, 0));
                    
pDC->SetBkColor(RGB(255, 0, 0));
                    
return brh;
                
case IDC_COMBO2:
                    
pDC->SetTextColor(RGB(255,255, 0));
                    
pDC->SetBkColor(RGB(255, 0, 0));
                    
return brh;
                }
            }
        }
    }

    
return hbr;
}

실행화면


예상했던것과는 코드가 좀 다르죠?
에디트의 페어런트는 콤보박스이지만, 리스트의 페어런트는 콤보박스가 아니고...
템퍼러리 윈도우가 됩니다.
저 리스트박스가 뜨는 원리는 흡사 메뉴가 뜨는것과 비슷한 형식으로 구동되는것 같은데
내부 로직이야 알 수가 없으니.. -_-;;;

리스트가 나올려면 에디트를 꾹 눌러야 나오니까..
현재 포커스가 당연히 있을 테고, 그 포커스가 있는 에디트를 기준으로..
콤보박스의 아이디를 구한겁니다.

이렇게 드롭다운 스타일일 경우는 에디트를 기준으로 콤보박스의 아이디를 구했는데..
드롭리스트 스타일은 에디트가 아니라 스태틱 컨트롤이라고 이전 장에서 알려드렸습니다.
그래서 드롭 리스트 스타일일 경우는 저 방법으로 처리가 불가능해집니다.

그럼 드롭다운 콤보와 드롭리스트 콤보를 2개 놓고 색상을 처리해 보도록 하겠습니다.

[콤보2를 드롭리스트 스타일로 변경합니다.]

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    
if(nCtlColor == CTLCOLOR_LISTBOX )
    {
        
if(pWnd->GetDlgCtrlID() == 1000)
        {
            
// 현재 포커스가 있는 윈도우를 구한다.
            
pWnd = pWnd->GetFocus();
            
if(pWnd && pWnd->GetParent())
            {
                
// 심플이나 드롭다운일 경우는 에디트에 포커스가 있으므로
                
// 페어런트의 컨트롤 아이디를 구한다페어런트가 콤보박스이다.
                
switch(pWnd->GetParent()->GetDlgCtrlID())
                {
                
case IDC_COMBO1:
                    
pDC->SetTextColor(RGB(0,255, 0));
                    
pDC->SetBkColor(RGB(255, 0, 0));
                    
return brh;
                
case IDC_COMBO2:
                    
pDC->SetTextColor(RGB(255,255, 0));
                    
pDC->SetBkColor(RGB(255, 0, 0));
                    
return brh;
                }
            }
        }
    }

    
return hbr;
}

이로써 콤보박스가 여러개 또는 여러가지 스타일로 섞여 있더라도 개별적으로 찾아서
원하는 색상과 배경을 넣어 줄 수 있게 되었습니다.

콤보의 색상을 처리하면서 느꼇던 점은.. ( 사실 콤보 색상변경은 저도 이번에 첨 해본겁니다. )
윈도우는 어떻게든 부모, 자식, 형제를 찾다보면 모두 거미줄 처럼 이어져 있기 때문에..
언젠가는 원하는 것을 찾을 수 있다는 점이었습니다.

자, 뒤바뀐 순서를 다시 복귀 시켜서 다음에는 콤보에 데이터를 추가하고, 삭제하고 하는 등의
기본적인 용법에 대하여 다루어 보겠습니다.

95.zip
0.15MB

에디트 컨트롤 편에서와 마찬가지고 WM_CTLCOLOR 라는 이벤트를 이용하여 글자색과 배경색을 변경할 수 있다.

클래스 위저드에서 WM_CTLCOLOR 을 선택한 후에 Add Function 버튼을 눌러 이벤트 핸들러를 추가한다.

저걸 추가하고 나면 화면상에 다음과 같은 코드가 자동으로 추가됩니다.

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

나는 Text 컨트롤을 대상으로 작업을 하므로 CTLCOLOR_STATIC 를 사용할 것입니다.
그럼 다음과 같은 코드를 추가해 봅니다.

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    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 이라고 변경한다.
그리고 다음과 같이 코드를 변경한다.

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    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;
}


실행 결과 화면은 다음과 같다

23.zip
0.04MB

저번에 이어 에디트 컨트롤을 사용하면서 글자색이나 배경색을 바꾸는 것에 대하여 알아보자.
이 기능은 에디트 컨트롤 뿐만 아니라, 거의 모든 문자열 입출력이 있는 컨트롤에 해당하는 기능이므로
잘 알아두면 다른 컨트롤에서도 쉽게 사용할 수 있다.

다이알로그의 이벤트 중에 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)으로 바꿔라 입니다.

여러개를 한꺼번에 바꾸거나, 그런건 머 위의 코드를 약간 수정하면 될테니 그건 손수 한번 해보세요.

다음에는 에디트 컨트롤의 폰트를 한번 변경해 보도록 하겠습니다.

13.zip
0.03MB

+ Recent posts