I'm trying to figure out how to change the edit box colour when I click on the button. Btw, i'm using VC++ 6.0 (MFC).

One way I can do is assign a colour variable. When I click the button, the colour variable changes. When the program call the OnDraw function, it check whether the pWnd->GetDlgCtrlID() == EditBoxID. If it matches then set the background colour/text colour etc.

Is there any other better way of doing that..? Lets say I have 200 different controls, if I want to use the method above, then my OnDraw function would have 200 different if statements and that would make my code very yucky and general instead of control specific..

Please advice..
Thanks..

Recommended Answers

All 7 Replies

You probably should be overriding the OnCtrlColor handler of the parent window.

Intercepting OnDraw for all your edit boxes sounds tedious.

Thanks..
If I use OnCtrlColour handler, when is the function called..? Is it everytime the the dialog is reload/refresh or is it continuously called independent of what I do..?

How do i pass the required parameters (CDC* pDC, CWnd* pWnd, UINT nCtlColor) to the function..?

If lets say i have 200 different editboxes, is it that I need to write the following code below..?
That would make the OnCtlColor function very long write..?

HBRUSH CZilchDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
   // Call the base class implementation first! Otherwise, it may
   // undo what we're trying to accomplish here.
   HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

   if (pWnd->GetDlgCtrlID() == IDC_EDIT1)
   {
      // Set the text color to red
      pDC->SetTextColor(RGB(255, 0, 0));

      // Set the background mode for text to transparent 
      // so background will show thru.
      pDC->SetBkMode(TRANSPARENT);

      // Return handle to our CBrush object
      hbr = m_brush;
   }


   if (pWnd->GetDlgCtrlID() == IDC_EDIT2)
   {
      // Set the text color to red
      pDC->SetTextColor(RGB(255, 0, 0));

      // Set the background mode for text to transparent 
      // so background will show thru.
      pDC->SetBkMode(TRANSPARENT);

      // Return handle to our CBrush object
      hbr = m_brush;
   }


   if (pWnd->GetDlgCtrlID() == IDC_EDIT3)
   {
      // Set the text color to red
      pDC->SetTextColor(RGB(255, 0, 0));

      // Set the background mode for text to transparent 
      // so background will show thru.
      pDC->SetBkMode(TRANSPARENT);

      // Return handle to our CBrush object
      hbr = m_brush;
   }

   ...

   if (pWnd->GetDlgCtrlID() == IDC_EDIT200)
   {
      // Set the text color to red
      pDC->SetTextColor(RGB(255, 0, 0));

      // Set the background mode for text to transparent 
      // so background will show thru.
      pDC->SetBkMode(TRANSPARENT);

      // Return handle to our CBrush object
      hbr = m_brush;
   }

   return hbr;
}

Thanks.

If I use OnCtrlColour handler, when is the function called..? Is it everytime the the dialog is reload/refresh or is it continuously called independent of what I do..?

MSDN says;
"The framework calls this member function when a child control is about to be drawn." In practice, this means that it gets called very frequently.

>> How do i pass the required parameters (CDC* pDC, CWnd* pWnd, UINT nCtlColor) to the function..?
You don't need to do anything about that, MFC handles the parameters for you automatically.

The nCtlColor parameters specifies what kind of control needs to painted, so if you want to paint edit controls only, then ..

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

  // Are we painting an edit control?
  if(nCtlColor == CTLCOLOR_EDIT)
  {
    // Yes ...
    // Set the text color to red
    pDC->SetTextColor(RGB(255, 0, 0));
    ...
  }

  return hbr;
}
// Are we painting an edit control?
  if(nCtlColor == CTLCOLOR_EDIT)
  {
    // Yes ...
    // Set the text color to red
    pDC->SetTextColor(RGB(255, 0, 0));
    ...
  }

MSDN also says

To change the background color of a single-line edit control, set the brush handle in both the CTLCOLOR_EDIT and CTLCOLOR_MSGBOX message codes, and call the CDC::SetBkColor function in response to the CTLCOLOR_EDIT code.

so that if statment should be a little more complex (or have further else if clauses.

@mrnobody all of those if statements contain the same block of code so I would not do it like that. If you have direct control of the values IDC_EDIT1 - IDC_EDIT200 arrange the values so that you can implement the condition IDC_EDIT1 <= ID <= IDC_EDIT200 or find some other short cut to answer the question, is it one of my edit boxes.

commented: Yes, a good catch +5

The code above would be possible if i want to paint all the 200 edit control the same colour right..?
What if I want to paint them different colour..?

Is it possible to do the following..?


1) Program load (first time)
2) Get the pDC* value of each edit control and store into a variable. For example

HBRUSH CZilchDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
//Since the setting of the colour is based on the pDC value, do the following to get each pDC value for the respective edit control.
if (pWnd->GetDlgCtrlID() == IDC_EDIT1)
{
    //store the pDC value into variable pDC_EDIT1
}

if (pWnd->GetDlgCtrlID() == IDC_EDIT2)
{
    //store the pDC value into variable pDC_EDIT2
}
}

3) At button click event, set the edit control by using the pDC values obtained earlier. For example

pDC_EDIT2->SetTextColor(RGB(255, 0, 0));
pDC_EDIT2->SetBkMode(TRANSPARENT);

pDC_EDIT10->SetTextColor(RGB(0, 255, 0));
pDC_EDIT10->SetBkMode(TRANSPARENT);

The code above would be possible if i want to paint all the 200 edit control the same colour right..?

Yes.

>> What if I want to paint them different colour..?
Then you have to arrange so that the colour/control mappings are stored somewhere. Just an idea, a std::map might be handy ..

// A map ..
std::map<int /* control ID */, COLORREF /* the colour */> id_to_color;

// Then in the handler ..
HBRUSH CZilchDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

  // Should we change the attribute(s)?
  if( < the condition here > )
  {
    // Get the edit control's id ..
    int control_id = pWnd->GetDlgCtrlID();
    
    // Use the current mapped colour ..
    pDC->SetTextColor(id_to_color[control_id]);
  }

  return hbr;
}

Perhaps start by trying out something that simple to get some insight.

>> Is it possible to do the following..?
Don't store anything that is passed into the handler, those are pointers to temporary objects i.e. for a given edit control, the passed-in CDC * will vary/change.

PS. Are you serious about having 200 edit controls? I think the maximum number of any controls on a dialog is 255, so watch out for that limit.

Thanks for the info. And no, i do not plan to use 200 edit controls.. lol...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.