Altering the Background and Text Color of a Control

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

A Simple Way to Alter the Background and Text Color of a Control (VC++)

, Vienna (Austria).

Environment: VC6

  1. Start by adding a handler for message WM_CTLCOLOR to the window containing the control (usually a CDialog derived class).
  2. Then, assuming m_colorBk to be the variable storing the desired background color of your control, add a block of code like this:


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

    CBrush Brush;
    COLORREF MyColor;
    MyColor = m_colorBk;

    // TODO: Change any attributes of the DC here
    if (nCtlColor == CTLCOLOR_EDIT)
    {
    Brush.CreateSolidBrush(MyColor);
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetBkColor(MyColor);

    // Set the text color to something that can be read on the
    // given background color

    COLORREF rgbText;
    int r, g, b, rt, gt, bt;
    div_t Result;
    Result = div(m_colorBk, 256);
    r = Result.rem; rt = 255 – r;
    Result = div(Result.quot, 256);
    g = Result.rem; gt = 255 – g;
    b = Result.quot; bt = 255 – b;
    if ((abs(rt-r)<50) && (abs(gt-g)<50) && (abs(bt-b)<50))
    rgbText = RGB(0,0,0);
    else
    rgbText = RGB(rt,gt,bt);
    pDC->SetTextColor(rgbText);
    hbr = (HBRUSH)Brush;
    Brush.DeleteObject();
    }

    // TODO: Return a different brush if the default is
    // not desired

    return hbr;
    }

    As you perhaps noticed, I used the div() function to compute the quotient and the remainder when dividing one integer by another. So, do not forget to include “math.h”!

  3. Create a new Class derived from the control class (let’s say an edit control).
  4. Declare a variable of the new type as a member of your CSomeDlg class.


    CMyClass m_edit_1;
  5. Map a variable to the control (let’s say m_strEdit_1).
  6. Subclass the control (within the OnInitDialog for a dialog derived class).


    m_edit_1.SubclassDlgItem(IDC_EDIT_1, this);

    where IDC_EDIT_1 is the resource ID of your control.

  7. Add a handler for message WM_ERASEBKGND to the new CMyClass class, with a code block like this:


    BOOL CMyClass::OnEraseBkgnd(CDC* pDC)
    {
    // TODO: Add your message handler code here and/or call default
    CSomeDlg *pMain = (CSomeDlg *)AfxGetMainWnd();

    CRect rcClient;
    GetClientRect(&rcClient);
    CBrush Brush;
    COLORREF MyColor;
    MyColor = pMain->m_colorBk;
    Brush.CreateSolidBrush(MyColor);
    pDC->FillRect(&rcClient, &Brush);
    Brush.DeleteObject();
    pDC->SetBkColor(MyColor);

    return CEdit::OnEraseBkgnd(pDC);
    }

  8. Add a handler for message =EN_CHANGE to the new CMyEdit new class, with a code block like this:


    void CMyClass::OnChange()
    {
    // TODO: If this is a RICHEDIT control, the control will not
    // send this notification unless you override the
    // CEdit::OnInitDialog()
    // function and call CRichEditCtrl().SetEventMask()
    // with the ENM_CHANGE flag ORed into the mask.

    // TODO: Add your control notification handler code here
    CSomeDlg *pMain = (CSomeDlg *)AfxGetMainWnd();
    pMain->UpdateData(true);
    }

    The code above is particularly important when the system tries to update your application’s window.

    If you forget that, you’ll be disapointed seeing that your text within the edit control has vanished when your application’s window again becomes top most on the screen!

Downloads

Download demo – 19.1 Kb

Download source – 21.3 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read