Emile
Emile

Reputation: 602

Change text and background color from a CEdit derived class

I have a derived class from CEdit and I want to change the text and background color. I've tried with the messages ON_WM_CTLCOLOR_REFLECT and ON_WM_CTLCOLOR, but I never receive these messages. Is there another option beside ON_PAINT ?

Here's how I initialize my CColorEdit control:

//in my dialog.h
CColorEdit m_test;
//in .cpp
DDX_Control(pDX, IDC_TEST, m_test);

I can't set the color manually like this :

m_test.SetTextColor(...);

Here's how I've tried to handle ON_WM_CTLCOLOR :

BEGIN_MESSAGE_MAP(CColorEdit, CEdit)
    ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

HBRUSH CColorEdit::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CEdit::OnCtlColor(pDC, pWnd, nCtlColor);
    if (m_theme != 0)
    {
        pDC->SetTextColor(RGB(0, 255, 0));
    }
    return hbr;
}

Here's my try with WM_CTLCOLOR_REFLECT :

BEGIN_MESSAGE_MAP(CColorEdit, CEdit)
    //{{AFX_MSG_MAP(CColorEdit)
    ON_WM_CTLCOLOR_REFLECT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CColorEdit::SetTextColor(COLORREF textColor)
{
    m_textColor = textColor;
    Invalidate();
}
void CColorEdit::SetBkColor(COLORREF backgroundColor)
{
    m_backgroundColor = backgroundColor;
    m_brBkgnd.DeleteObject();
    m_brBkgnd.CreateSolidBrush(backgroundColor);
    Invalidate();
}

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
    pDC->SetBkColor(m_backgroundColor);
    pDC->SetTextColor(m_textColor);

    if (nCtlColor)       // To get rid of compiler warning
        nCtlColor += 0;

    return hbr;
}

Thx.

Upvotes: 2

Views: 4900

Answers (2)

Andrew Truckle
Andrew Truckle

Reputation: 19107

Look here. To quote:

It was a real challenge for me to make a simple change of background color for CEdit. I was suprised to find out that there are no standard function, like CEdit::SetBkColor, to do this.

First step is to create class derived from CEdit and declare function CtlColor:

// CustomEdit.h
class CCustomEdit : public CEdit
{
protected:
  HBRUSH CtlColor(CDC *pDC, UINT);
  DECLARE_MESSAGE_MAP()
};

Second, handle WM_CTLCOLOR_REFLECT event:

// CustomEdit.cpp
BEGIN_MESSAGE_MAP(CCustomEdit, CEdit)
  ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()

HBRUSH CCustomEdit::CtlColor(CDC *pDC, UINT)
{
  COLORREF bkColor = RGB(255, 255, 255);
  pDC->SetBkColor(bkColor);
  return CreateSolidBrush(bkColor);
}

So you need to use both of them!

Upvotes: 2

Constantine Georgiou
Constantine Georgiou

Reputation: 3401

If you made the CColorEdit class only for performing this kind of custom color drawing, it wasn't needed, because you can simply process the WM_CTLCOLOR messages in the parent window. The message is actually WM_CTLCOLOREDIT (WM_CTLCOLOR was used in old windows versions), however MFC maps all WM_CTLCOLORxxxx messages to the ON_WM_CTLCOLOR handler and passes the control-type as a paremeter.

Here is some code:

#define COLOR_YELLOW RGB(255,255,0)
HBRUSH hBrYellow = []() { return CreateSolidBrush(COLOR_YELLOW); }();

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    // Our custom edit-control
    if (nCtlColor == CTLCOLOR_EDIT && pWnd->GetDlgCtrlID() == IDC_MYCUSTOMEDIT)
    {
        pDC->SetBkColor(COLOR_YELLOW);
        return hBrYellow;
    }

    // All the rest
    return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
}

This code sample sets the background color of the edit-control to yellow. The edit-control is a simple and standard windows edit-box, no need for subclassing.

Upvotes: 1

Related Questions