Solved

Edit Box color - example?

Posted on 2006-10-28
10
1,416 Views
Last Modified: 2013-11-20
I'm trying to understand how to change the background color of an edit box. I have read a number of items on this, but most are offering a prewritten class, or presume knowledge I do not yet have. So, Suppose I have a dialog (MyDlg) with one editbox (IDC_EDIT) and one button (IDC_BUTTON). I want to push the button IDC_BUTTON and make the background of edit box IDC_EDIT red. This is the simplest example I can think of, and I hope I can see the code to do this so I can use it to gain an understanding of what is involved. Thanks.
0
Comment
Question by:Elliot123
  • 5
  • 3
  • 2
10 Comments
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 250 total points
ID: 17826213
The following code shows how to set background color to red in all edit boxes on a dialog. You can set it dynamically by replacing hard-coded color and brush with values created according to user selection.

HBRUSH m_hBrush;    // dialog class member

m_hBrush = ::CreateSolidBrush(RGB(255, 0, 0));   // add this to OnInitDialog function

// WM_CTLCOLOR message handler
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    if ( nCtlColor == CTLCOLOR_EDIT )
        pDC->SetBkColor(RGB(255, 0, 0));

    if ( nCtlColor == CTLCOLOR_EDIT  || nCtlColor == CTLCOLOR_MSGBOX )
        return m_hBrush;

    return hbr;
}

See details in MSDN topic CWnd::OnCtlColor.
0
 
LVL 5

Accepted Solution

by:
NickGeorghiou earned 250 total points
ID: 17826226
Hi,

You need to implement the ON_WM_CTLCOLOR handler of the dialog. Here is an example of the OnCtlColor function. I think it will work, I haven't compiled it, but it should give you a good start:

HBRUSH RCDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    long foreColour = RGB(255,255,255); // White
    long backColour = RGB(0,0,128); // Blue

    // 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==GetDlgItem(IDC_EDIT))
    {
        // Set the text color
        pDC->SetTextColor(foreColour);

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

        // Create brush for painting the control
        DeleteObject(mBackBrush);
        mBackBrush = CreateSolidBrush(backColour);

        // Return handle to our brush object
        hbr = mBackBrush;
    }

   // return the handle to the brush that
   // the control will be painted with
   return hbr;
}

Cheers,
Nick
0
 
LVL 5

Expert Comment

by:NickGeorghiou
ID: 17826230
Sorry Alex,
Didn't see your post - overlapping again, doh!
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 5

Expert Comment

by:NickGeorghiou
ID: 17828231
Hey guys,
Just had a quick review of the two examples and wanted to point out a couple of things:

1. In the code I provided, the check to identify a control (i.e. for IDC_EDIT) should be:
if (pWnd->GetDlgCtrlID() == IDC_EDIT)

2. In my code mBackBrush is intended to be a member of type HBRUSH of the dialog, (I assume this is the same for m_hBrush in Alex's example?)

3. The difference b/n the two implementations above is that Alex's version will only highlight the background behind any text that is typed into the edit box where as my version will set the entire background to the chosen colour even without any text typed into it.

Cheers,
Nick

0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17828238
>> The difference b/n the two implementations above is that Alex's version will only highlight the background behind any text that is typed into the edit box where as my version will set the entire background to the chosen colour even without any text typed into it.

My version hightlights the whole background.
0
 
LVL 5

Expert Comment

by:NickGeorghiou
ID: 17828258
Hey Alex,

I was just about to write that I tested your version and it only did the area behind the text but then... I had another look at what you wrote...

1000 apologies mate - I only looked at your OnCtlColor function and completely missed the two lines before it. Will be more careful next time. Sorry for the false assertion...

Regds,
Nick
0
 

Author Comment

by:Elliot123
ID: 17830624

We have glorious color! I have a simple dialog with two edit boxs and five buttons. Two buttons target one or the other edit box for text and color change. Three buttons choose a color and change the RGB settings to make that color.  I can choose the edit box to change, then choose the color (Text and background) for that edit box. Here's what I ended up with.

      HBRUSH m_BackBrush;       
int nEditToColor;
      long foreColor;
      long backColor;
0
 

Author Comment

by:Elliot123
ID: 17830835
(Sorry. I hit the wrong button and posted only part of my reply)

We have glorious color! I have a simple dialog with two edit boxs and five buttons. Two buttons target one or the other edit box for text and color change. Three buttons choose a color and change the RGB settings to make that color.  I can choose the edit box to change, then choose the color (Text and background) for that edit box. Here's what I ended up with, almost 100% taken from Alex and Nick's code.

In TestColorsDlg.h the following are added as members of class TestColorsDlg.
     HBRUSH m_BackBrush;      
     int nEditToColor;
     long foreColor;
     long backColor;
************************************************************
In TestColorsDlg.cpp the following is added to CTestColorsDlg::OnIntDialog
    m_BackBrush = ::CreateSolidBrush(RGB(255,0,0));  
    nEditToColor = 0;
************************************************************
In TestColorsDlg.cpp use Wizard to add a handler for ObjectID = CTestColorsDlg, Message = WM_CTLCOLOR
    HBRUSH CTestColorsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
   {      
      HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

//      if(pWnd == GetDlgItem(IDC_EDIT2))  //<--works if IDC_EDIT2 has a control var set by wizard
//      if(pWnd == GetDlgItem(nEditToColor))
      if (pWnd->GetDlgCtrlID() == nEditToColor)
      {
            pDC->SetTextColor(foreColor);
            pDC->SetBkMode(TRANSPARENT);
            DeleteObject(m_BackBrush);
            m_BackBrush = CreateSolidBrush(backColor);
            hbr = m_BackBrush;
      }
      return hbr;
}
**************************************************************************
Add button functions to control which edit box is selected for change, and what the text/background color combination will be.
void CTestColorsDlg::OnButton1()
{
      nEditToColor = IDC_EDIT1;      //<--works changing edit box color
//      nEditToColor = IDC_BUTTON_Test;//<--does not work changing button color      
}
void CTestColorsDlg::OnButton2()
{
      nEditToColor = IDC_EDIT2;
}
void CTestColorsDlg::OnBUTTONRed()
{
      foreColor = RGB(0,0,255);
      backColor = RGB(255,0,0);
      GetDlgItem(nEditToColor)->SetWindowText("RED"); //<--works sending text to edit box or button
}
void CTestColorsDlg::OnBUTTONBlue()
{
      foreColor = RGB(255,0,0);
      backColor = RGB(0,0,255);
      GetDlgItem(nEditToColor)->SetWindowText("BLUE");
}
void CTestColorsDlg::OnBUTTONGreen()
{
      foreColor = RGB(0,0,0);
      backColor = RGB(0,255,0);
      GetDlgItem(nEditToColor)->SetWindowText("GREEN");
}
*******************************************************************************
Two observations:
First, as Nick noted,   if(pWnd == GetDlgItem(IDC_EDIT2)   did not work. However, as I worked with it, i discovered it would work just fine if I created a control variable for IDC_EDIT2. I never used the control variable anywhere, but its existence made the line of code work. ???

Second, since I was doing so well changing the colors of edit boxes, I decided to try to use the same technique to change the colors of  a button. So, I added button IDC_BUTTON_Test, and used it exactly as I had used edit box IDC_EDIT1. The text changes in IDC_BUTTON_Test, but neither the background color nor the text color changes. I don't see anything in the code that would limit it to boxes, so I must be missing something. Ideas?

Many thanks for the help.

0
 
LVL 5

Expert Comment

by:NickGeorghiou
ID: 17831110
Hi Elliot123,

Unfortunately as you have discovered the WM_CTLCOLOR message does not work for buttons. If you want to change the color of a button you need to have your own owner-draw button derived from CButton and override the DrawItem function (at the very least). This is getting a little bit more complicated so I will refer you to this example:

http://www.codeguru.com/cpp/controls/buttonctrl/advancedbuttons/article.php/c8395/

It is very simple to get working so don't be discouraged that I have pointed you to a prewritten class (I know you requested not to in your original question). If you download the ColoredButton_src.zip (near the bottom of the page) it contains ColorButton.h and ColorButton.cpp which provide a class derived from CButton called CColorButton that you can change colour for. Follow these simple steps and you should be able to get it to work and at the same time you can have a look at the ColorButton implementation to see how it is done.

1. Add ColorButton.h and ColorButton.cpp to your project.
2. Add   #include "ColorButton.h" to your dialogs header file.
2. Recreate the ClassWizard file (simply delete the existing .clw file and next time you try to perform a class wizard function it recreates it). Do this so that the class wizard picks up the ColorButton.
3. In the ClassWizard go to Member Variables tab and double-click IDC_BUTTON_Test. Add a new variable with Category set to "Control" and Variable set to "CColorButton".
4. Now all you have to do is call the SetColor function on the button member to change its color. e.g.

m_btnTest->SetColour(foreColor, backColor);

Hope this helps,
Regds,
Nick

0
 

Author Comment

by:Elliot123
ID: 17923211
Guys,

I hope I succeeded in splitting the points. I thought I did this last week, but noticed today that it didn't work. Thanks for the help
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to create frequencies of a variable from SAS dataset? 10 133
Get filename and folder into excel 7 79
unable to delete all specified values regedit 38 576
if loop in java 3 154
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question