Changing the Background Color of Edit Controls

.




Click here for larger image

This is the 2nd revision to the original article. I would like to thank everyone who posted comments and any answers to those comments that I’ve used in this latest revision.

If you need to change the background color of CEdit controls on your dialog, it is very simple ! (you don’t need to derive your own class from CEdit).

The following example will change the appearance of specific CEdit controls including:

  1. Background color.
  2. Text color.
  3. Transparency.

I chose Blue and Red backgrounds with White text for this example.

In your CTestDlg header file, declare member variables from CBrush and COLORREF:

class CTestDlg : public CDialog
{
protected:
 CBrush m_redbrush,m_bluebrush;
 COLORREF m_redcolor,m_bluecolor,m_textcolor;
};

Then, add these lines in the OnInitDialog function:

BOOL CTestDlg::OnInitDialog()
{
 m_redcolor=RGB(255,0,0);                      // red
 m_bluecolor=RGB(0,0,255);                     // blue
 m_textcolor=RGB(255,255,255);                 // white text
 m_redbrush.CreateSolidBrush(m_redcolor);      // red background
 m_bluebrush.CreateSolidBrush(m_bluecolor);    // blue background
}

Finally do this on the ID_CTLCOLOR handle:

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

  switch (nCtlColor)
  {
  // process my edit controls by ID.
  case CTLCOLOR_EDIT:
  case CTLCOLOR_MSGBOX:
    switch (pWnd->GetDlgCtrlID())
    {
  // first CEdit control ID
    case IDC_MYCONTROLNAME1:         // put your own CONTROL ID
                                     // here
      pDC->SetBkColor(bluecolor);    // change the background
                                     // color [background colour
                                     // of the text ONLY]
      pDC->SetTextColor(textcolor);  // change the text color
      hbr = (HBRUSH) m_bluebrush;    // apply the blue brush
                                     // [this fills the control
                                     // rectangle]
      break;
    // second CEdit control ID
    case IDC_MYCONTROLNAME2:         // make the TEXT transparent,
                                     // but control is still
                                     // filled with the brush
                                     // color!
      pDC->SetBkMode(TRANSPARENT);   // make background
                                     // transparent [only affects
                                     // the TEXT itself]
      pDC->SetTextColor(textcolor);  // change the text color
      hbr = (HBRUSH) m_redbrush;     // apply the red brush
                                     // [this fills the control
                                     // rectangle]
      break;
    case IDC_MYCONTROLNAME3:         // Make the text and the
                                     // control rectangle
                                     // transparent, so the
                                     // dialog window
                                     // color/bitmap draws
                                     // through.
      pDC->SetBkMode(TRANSPARENT);   // make background
                                     // transparent [only affects
                                     // the TEXT itself]
      pDC->SetTextColor(textcolor);  // change the text color
      hbr = m_brush;                 // Return handle to our
                                     // CBrush object [this is
                                     // the brush you've used to
                                     // paint the dialog window.
      break;
    // otherwise, do default handling of OnCtlColor
    default:
      hbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
      break;
    }
    break;
  // process Static text, READONLY controls, DISABLED * controls.
  // * NOTE: Disabled controls can NOT have their text color
  //         changed.
  //         Suggest you change all your DISABLED controls to
  //         READONLY.
  case CTLCOLOR_STATIC:
    // process my edit controls by ID
    switch (pWnd->GetDlgCtrlID())
    {
    // one of my READONLY edit controls (could also be disabled or
    // static text)
    case IDC_MYCONTROLNAME4:
      pDC->SetBkColor(bluecolor);   // change the background color
      pDC->SetTextColor(textcolor); // change the text color
      hbr = (HBRUSH) m_bluebrush;   // apply the brush
      break;
    // otherwise, do default handling of OnCtlColor
    default:
      hbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
    }
    break;
  // otherwise, do default handling of OnCtlColor
  default:
    hbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
  }

  return hbr; // return brush
}

I hope this code helps you as much as other articles on CodeGuru have helped me.

Miscellaneous Notes/Comments:

Windows CE, READONLY controls: [posted by Tony].

Code works great in EVC++/MFC app. However, for read-only edit boxes, use CTLCOLOR_BTN instead of CTLCOLOR_STATIC in the test of nCtlColor.

READONLY and DISABLED controls are processed using CTLCOLOR_STATIC!

If your controls are set to DISABLED, then you CAN NOT alter the text color; if you want this ability, change all your DISABLED controls to READONLY.

TRANSPARENCY: pDC->SetBkMode(TRANSPARENT;)DOES NOT MAKE THE WHOLE CONTROL TRANSPARENT! it only affects the text itself.
Think of it this way: The control rectangle is filled using the BRUSH, then the text is drawn on top using a background and foreground color. So, to make the entire control transparent, you need to use the above SetBkMode command, and also set the controls brush to the same brush you have used to draw the window itself.

Brief Example:

  1. Add a bitmap resource to your project.
  2. In your class header add a CBitmap variable, such as:
  3. class CMyDialog : public Dialog
    {
    public:
      CBitmap bitmapBackground;
    ...
    
  4. In your class source, load the bitmap up in OnInitDialog:
  5. BOOL CMyDialog::OnInitDialog()
    {
      bitmapBackground.Attach(Loadbitmap(AfxGetInstanceHandle(),
    MAKEINTRESOURCE(IDB_BACKGROUND) ) );
    ...
    
  6. Add OnEraseBkgnd to your class:
  7. BOOL CMyDialog::OnEraseBkgnd(CDC * pDC)
    {
      // center the bitmap in the window
      CRect rect;GetClientRect(&rect);
    
      CDC dc; dc.CreateCompatibleDC(pDC);
      CBitmap * pOldBitmap = dc.SelectObject(&bitmapBackground);
      BITMAP bitmap; bitmapBackground.GetObject(sizeof(BITMAP),
             &bitmap);
    
      int x=(rect.Width()-bm.bmWidth)/2+rect.left;
      int y=(rect.Height()-bm.bmHeight)/2+rect.top;
      pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dc,0,0,SRCCOPY);
      // center the bitmap
    
      // you could stretch the bitmap to fill the window!
      // pDC->StretchBlt(rect.left,rect.top,rect.Width(),
                         rect.Height(),&dc,0,0,bm.bmWidth,
                         bm.bmHeight,SRCCOPY);
    
      dc.SelectObject(pOldBitmap);
      pDC->SetBkMode(oldbackmode);
    
      return TRUE;
    }
    
  8. Write your custom OnCtlColor handler:
  9. HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd,
                                UINT nCtlColor)
    {
      HBRUSH hbr;
    
      switch (nCtlColor)
      {
      // process my edit controls by ID.
      case CTLCOLOR_EDIT:
      case CTLCOLOR_MSGBOX:
        switch (pWnd->GetDlgCtrlID())
        {
        // first CEdit control ID
        case IDC_MYCONTROLNAME1:
    // put your own CONTROL ID here
          pDC->SetBkMode(TRANSPARENT);  // make text
                                        // background transparent
          pDC->SetTextColor(RGB(255,0,0));
    // change the text color to red.
          hbr = (HBRUSH) GetStockObject(NULL_BRUSH);
    // apply a null brush, so control's rectangle
    // isn't filled.
          break;
    // otherwise, do default handling of OnCtlColor
      default:
          hbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
      }
    
      return hbr;    // return brush
    }
    

Further Reading:

Colored/Blinking Controls and Dialogs with any Font by Yury Goltsman.

History:

Original article posted: March 13, 2001

Date Last Updated: May 19, 2003

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read