메뉴 닫기

MFC에서 CBrush와 OnCtlColor로 배경 색상 변경하는 방법


MFC에서 CBrush와 OnCtlColor로 배경 색상 변경하는 방법

🎨 MFC에서 원하는 색상으로 배경과 텍스트를 꾸며보세요

윈도우 애플리케이션을 개발할 때 배경색이나 텍스트 색상을 바꾸고 싶었던 적 있으신가요?
MFC에서 제공하는 OnCtlColorCBrush 클래스를 활용하면 매우 간단하게 사용자 지정 색상으로 UI를 꾸밀 수 있습니다.
개발자라면 한 번쯤 만나봤을 이 기능을 통해 인터페이스를 더 깔끔하고 직관적으로 만들 수 있죠.
오늘은 초보자도 따라할 수 있도록 아주 쉽게 설명드릴게요.

이번 글에서는 OnCtlColor 메시지를 처리하여 컨트롤의 배경색 또는 텍스트 색상을 변경하는 방법과, CBrush를 생성하고 활용하는 기본적인 흐름을 알려드립니다.
또한 실무에서 자주 쓰이는 팁들도 함께 소개하니, 끝까지 읽으시면 분명 도움이 되실 거예요.







🖌️ CBrush란 무엇인가요?

MFC에서 배경색이나 텍스트 배경을 바꾸기 위해 가장 먼저 알아야 할 클래스가 바로 CBrush입니다.
CBrush는 GDI(Graphics Device Interface)에서 제공하는 브러시 객체로, 영역을 채우는 데 사용됩니다.
도형, 배경, 컨트롤 등 다양한 UI 요소의 색상을 변경할 때 핵심 역할을 하죠.

특히 윈도우 메시지 중 WM_CTLCOLOR 또는 MFC의 OnCtlColor를 사용할 때 CBrush 객체를 반환함으로써 컨트롤의 배경을 지정할 수 있습니다.
이때 브러시는 특정 색상으로 초기화되며, GDI에서 그 색으로 영역을 채우게 되는 구조입니다.

  • 🖼️CBrush::CreateSolidBrush(COLORREF color) – 단색 브러시 생성
  • 🎨RGB(255, 255, 255) – 흰색, RGB(0, 0, 0) – 검정색
  • 📌CBrush 객체는 멤버 변수로 선언해 소멸되지 않도록 관리해야 함

💬 CBrush를 올바르게 사용하면 UI의 시각적 완성도가 훨씬 높아집니다.
사용자 경험까지 고려한 배경 처리를 위한 첫걸음이라고 할 수 있어요.

이처럼 CBrush는 단순한 색상 지정 도구가 아니라, MFC에서 시각적 요소를 제어하는 중요한 도구입니다.
기초 개념을 확실히 익혀두면 이후 다양한 메시지 처리에도 유연하게 대처할 수 있습니다.


🎯 OnCtlColor의 기본 원리

MFC에서 배경이나 텍스트 색상을 변경하려면 OnCtlColor 함수의 동작 원리를 이해하는 것이 가장 중요합니다.
이 함수는 윈도우 컨트롤이 그려지기 전, GDI 객체(주로 브러시와 폰트)를 설정할 기회를 제공합니다.
즉, 시스템이 컨트롤을 그리기 직전에 호출되어 개발자가 원하는 스타일을 적용할 수 있도록 도와주는 역할을 하는 거죠.

OnCtlColor는 MFC의 CWnd::OnCtlColor로 오버라이드할 수 있으며, 다양한 컨트롤 유형에 따라 nCtlColor 값이 달라집니다.
예를 들어, 에디트 박스, 정적 텍스트, 리스트박스 등 각 컨트롤 유형별로 구분하여 처리할 수 있습니다.

  • 📌OnCtlColor 함수는 CDC* 포인터와 CWnd* 포인터를 인자로 받습니다
  • 🎨텍스트 색은 pDC->SetTextColor()로, 배경색은 pDC->SetBkColor()로 지정
  • 🖌️배경 채우기를 위한 브러시는 CBrush 객체를 반환해야 함
CODE BLOCK
// 예시 코드 - OnCtlColor 사용
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    if (nCtlColor == CTLCOLOR_STATIC)
    {
        pDC->SetTextColor(RGB(255, 255, 255));
        pDC->SetBkColor(RGB(0, 0, 128));
        return m_brushBackground;
    }

    return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}

이처럼 OnCtlColor는 MFC에서 시각적인 사용자 경험을 개선하기 위해 반드시 알아야 할 핵심 함수입니다.
단순한 색상 변경을 넘어서, 컨트롤별로 개별 스타일을 적용할 수 있는 유연성을 제공합니다.







🔧 배경 색상 변경하는 실습 코드

MFC에서 컨트롤의 배경 색상을 바꾸기 위한 실습 코드를 함께 살펴보겠습니다.
이번 예제는 정적 텍스트(static text)의 배경을 파란색으로 바꾸는 간단한 예시입니다.
핵심은 CBrush 객체를 생성하고 OnCtlColor 함수에서 이를 반환하는 구조에 있습니다.

CODE BLOCK
// 헤더 파일에 CBrush 멤버 변수 선언
class CMyDialog : public CDialogEx
{
    ...
    CBrush m_brushBlue;
    ...
};

// OnInitDialog에서 브러시 초기화
BOOL CMyDialog::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 파란색 브러시 생성
    m_brushBlue.CreateSolidBrush(RGB(0, 0, 255));

    return TRUE;
}

// OnCtlColor 오버라이드
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    if (nCtlColor == CTLCOLOR_STATIC)
    {
        pDC->SetBkColor(RGB(0, 0, 255));
        return m_brushBlue;
    }

    return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
}

💎 핵심 포인트:
브러시 객체는 전역 또는 멤버 변수로 선언해야 합니다. 그렇지 않으면 일시적으로 생성된 브러시가 사라져 UI에 문제가 발생할 수 있습니다.

위와 같은 구조로 작성하면 정적 텍스트의 배경이 파란색으로 적용되며, 깔끔한 시각 효과를 구현할 수 있습니다.
실제 프로젝트에서 다른 컨트롤에도 동일한 방식으로 적용할 수 있으니 참고해 보세요.


🌈 텍스트 색상도 바꿀 수 있나요?

네, 물론입니다.
MFC의 OnCtlColor를 활용하면 배경색뿐 아니라 텍스트 색상도 간편하게 변경할 수 있습니다.
기본적으로 텍스트 색상은 CDC::SetTextColor() 함수를 통해 지정할 수 있으며, 배경색과 함께 설정하면 더욱 눈에 띄는 인터페이스를 구성할 수 있습니다.

예를 들어, 흰색 배경에 진한 회색 텍스트를 적용하고 싶다면 아래 코드처럼 구현하면 됩니다.
이렇게 하면 눈에 부담을 줄이고 가독성을 높일 수 있죠.

CODE BLOCK
// 텍스트 색상과 배경색 모두 설정
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    if (nCtlColor == CTLCOLOR_STATIC)
    {
        pDC->SetTextColor(RGB(60, 60, 60));     // 진한 회색 텍스트
        pDC->SetBkColor(RGB(255, 255, 255));    // 흰 배경
        return m_brushWhite;
    }

    return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
}

💡 TIP: 텍스트 색상은 반드시 SetTextColor()로 먼저 설정한 뒤, 배경색을 SetBkColor()로 지정하는 순서가 일반적입니다.
이 순서를 지켜야 원하는 효과가 정확히 나타납니다.

또한 텍스트 스타일을 바꾸고 싶다면 폰트 객체를 따로 생성해 pDC->SelectObject()로 적용하면 됩니다.
이러한 조합을 활용하면 사용자 인터페이스에 세련된 디자인을 쉽게 구현할 수 있습니다.







💡 자주 하는 실수와 해결 팁

OnCtlColor와 CBrush를 처음 사용할 때 초보자들이 자주 실수하는 부분이 몇 가지 있습니다.
이러한 실수들은 예상치 못한 UI 오류나 충돌로 이어질 수 있으니 미리 숙지해두는 것이 좋습니다.
아래에서 대표적인 문제와 그 해결 방법을 소개해드릴게요.

  • ⚠️지역 변수로 선언한 CBrush는 함수가 끝나면 소멸됩니다. 반드시 멤버 변수로 선언하세요.
  • 🧼배경이 제대로 안 지워지는 현상은 배경색과 텍스트 배경색이 동일하지 않아서일 수 있습니다.
  • 🖌️Invalidate()를 적절히 호출하지 않으면 색상이 즉시 반영되지 않습니다.
  • 📌CTLCOLOR_EDIT, CTLCOLOR_LISTBOX 등 컨트롤 타입에 맞게 분기 처리를 해줘야 정상 동작합니다.

⚠️ 주의: 브러시를 DeleteObject()로 수동 소멸할 경우, 아직 사용 중인 컨트롤이 있을 수 있으므로 삭제 타이밍에 유의해야 합니다.

실제 현업에서도 위와 같은 실수로 인해 컨트롤이 깜빡이거나 배경이 제대로 칠해지지 않는 경우가 종종 발생합니다.
디버깅에 시간을 낭비하지 않도록 위 내용을 꼭 기억해두세요.
안정적인 UI 구현을 위한 작은 습관이 결국 완성도를 좌우합니다.


자주 묻는 질문 (FAQ)

OnCtlColor는 어떤 상황에서 호출되나요?
컨트롤이 화면에 그려지기 직전에 호출되며, 해당 시점에 텍스트 색상, 배경색, 폰트 등을 설정할 수 있는 기회를 제공합니다.
CBrush는 꼭 멤버 변수로 선언해야 하나요?
네, 지역 변수로 선언하면 함수 종료 시 메모리에서 해제되어 화면에 적용되지 않거나 오류가 발생할 수 있습니다.
모든 컨트롤에서 색상 변경이 가능한가요?
대부분의 표준 컨트롤에서는 가능하지만, 일부 사용자 정의 컨트롤이나 서드파티 컨트롤은 별도 처리가 필요할 수 있습니다.
텍스트 색상과 배경색을 동시에 설정해도 되나요?
가능합니다. 일반적으로 SetTextColor → SetBkColor 순으로 설정하면 원하는 효과를 얻을 수 있습니다.
Invalidate() 호출이 꼭 필요한가요?
색상 변경 후 즉시 반영되게 하려면 Invalidate()를 호출하여 화면을 갱신해주는 것이 좋습니다.
다이얼로그 전체 배경 색도 바꿀 수 있나요?
네, WM_ERASEBKGND 메시지를 처리하거나 OnPaint에서 직접 채우는 방식으로 다이얼로그 전체 배경도 변경할 수 있습니다.
다양한 색상의 브러시를 한 번에 관리할 수 있나요?
여러 개의 CBrush 멤버 변수를 만들어 각기 다른 색상으로 초기화해두고 조건에 따라 선택적으로 반환하면 됩니다.
다이얼로그 외에도 OnCtlColor를 사용할 수 있나요?
네, CFormView나 CPropertyPage 등 다른 MFC 기반 클래스에서도 동일하게 사용할 수 있습니다.



🧩 MFC에서 배경색과 텍스트 색을 바꾸는 핵심 요약

MFC를 활용한 UI 개발에서 CBrushOnCtlColor는 매우 강력한 도구입니다.
이 조합을 통해 정적인 컨트롤뿐만 아니라 다양한 윈도우 요소들의 배경 색상텍스트 색상을 자유롭게 조절할 수 있습니다.
브러시는 반드시 멤버 변수로 선언하고, 컨트롤 유형에 따라 적절한 분기 처리와 DC 설정 순서를 지키는 것이 중요합니다.
또한 Invalidate()UpdateData() 등을 통해 즉각적인 UI 반영도 고려해야 안정적인 결과를 얻을 수 있죠.

이번 글에서 소개한 예제와 팁을 잘 응용한다면, 단조로운 UI에서 벗어나 보다 직관적이고 세련된 MFC 프로그램을 구현할 수 있습니다.
초보자도 충분히 따라할 수 있는 실습 중심의 설명으로 구성했으니, 직접 적용해보며 실력을 키워보세요.


🏷️ 관련 태그 : MFC, CBrush, OnCtlColor, 배경색변경, 텍스트색상, 윈도우프로그래밍, VisualStudio, UI커스터마이징, C++, GDI