We help IT Professionals succeed at work.

Colors in Disabled DropList Combo Box

stolar asked
Medium Priority
Last Modified: 2013-11-20
Environment:  VC++ 4.0  Win95


What am I to do to show the edit control part of a Disabled-DropList-ComboBox in the colors of an enabled readonly edit control?  Or, in other words, all I want to do is to show the text of the above mentioned Disabled-DropList-ComboBox not dimmed, but black.

Overriding the OnCtlControl handler doesn't help - there is no problem to change the text background color, but the text color still appears dimmed.

Watch Question

You have to make your combo box ownerdraw enables. Now make sure you override the OnDrawItem of the combo box. In the ondrawItem you will have a structure DRAWITEMSTRUCT passed to you containing draw related stuff such as DC, hWnd, rect etc. Using this you can do individual textout's for each item by choosing a back color, fore color and font of your choice. However, the edit control of the combo box will need a different handling routine as combobox is a combination of a list box and edit box. Check a few samples in the Win32 SDK or the VC++ CD.


As you put it --

"The edit control of the combo box" -- that (and not the list control) is exactly the subject of my question -- "will need a different handling routine" -- what kind? -- "as combobox is a combination of a list box and edit box" -- I knew that -- "Check a few samples in the Win32 SDK or the VC++ CD." -- please give me a lead.

I still can't proceed...


Adjusted points to 100


Adjusted points to 150


Adjusted points to 200

OnCtlColor should work (in theory), set the text color as well as returning the background brush.

You will probably want to respond to CTLCOLOR_EDIT (but check which ones you actually get)

I seem to be changing colors ok for my own combo boxes.

I'll double check my own code and see if I can change the text color as well - but I don't see it being a problem.


Eager to hear from you --
Are you changing TEXT (and not only background) colors in your DISabled DropLIST combo boxes?  

Yeup - disabled controls always show text in grey (and the V-button on the combo-box drop down).

Had to respond to CTLCOLOR_STATIC to get background color to change - but text color wouldn't work unless the control is enabled.

Mind you - there is the question of WHY do you want to fiddle with the standard colors - its generally not a good thing to do as it can create confusion in the user (as if they don't get confused enough already).

I think the only colution would be an owner-drawn combo box where you have complete control over the drawing. However, even here the drop-down button will by grey instead black.



I have posted an article to Zafir Anjum's Home Page.  It contains a picture that illustrates my point.  

I don't want the V-button to appear in black, I want it to appear dimmed.

You may see the picture at

 You can do this easily with ownerdraw.  First, create a class derived from CComboBox and use ClassWizard to override DrawItem:

class CDisCombo : public CComboBox
//////////////// Irrelevant details omitted
// Overrides
      // ClassWizard generated virtual function overrides
      virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

  Next, fill in the code for DrawItem:

void CDisCombo::DrawItem(LPDRAWITEMSTRUCT lpDIS)
      if (-1 == lpDIS->itemData) // empty box or edit-part
      { return; }

      CString text;
      GetLBText(lpDIS->itemID, text);

      CDC dc;
      BOOL ok = dc.Attach(lpDIS->hDC);

      ok = dc.DrawText(text, &(lpDIS->rcItem), DT_LEFT);

      (void) dc.Detach();

  To use this combo in a dialog, you must add the combo to the resource, set the styles to drop list, owner draw fixed, and has-strings.  Next, add a member variable of type CDisCombo to your dialog:

#include "discombo.h"

class CDiscomboDlg : public CDialog
//////////////////// Irrelevant details omitted
        CDisCombo m_combo;

Finally, set up the combo in OnInitDialog:

BOOL CDiscomboDlg::OnInitDialog()
      VERIFY(m_combo.SubclassDlgItem(IDC_COMBO1, this));
      VERIFY(CB_ERR != m_combo.AddString("one"));
      VERIFY(CB_ERR != m_combo.AddString("two"));
      VERIFY(CB_ERR != m_combo.AddString("three"));

                 return TRUE;



I did exactly as being told.  It still DOES NOT give me the possibility to (quote from my original question) "show the text of the ... Disabled-DropList-ComboBox not dimmed, but black".

I will repeat it again:

The combo box is DISabled.  I want control over the color of the TEXT in the combo box's EDIT CONTROL.

What your method provides is --

A)  The possibility to control colors in the combo's LIST control.  I tried the following --

void CDisCombo::DrawItem(LPDRAWITEMSTRUCT lpDIS)
//MY COMMENT if (-1 == lpDIS->itemData) //empty box or edit part
//             { return; }

since it is the edit part I want to work with, but also in vain.  Placing a breakpoint on the following line I discovered that CDisCombo::DrawItem does not get called to process the edit part of the combo.

B) The combo box appears with the cursor blinking in the edit part and the text may be modified.  That's not my goal.  One can not change the text that appears in a DropLIST combo box.


NB:  In CDiscomboDlg::OnInitDialog() I have a CDialog::OnInitDialog() call after
VERIFY(CB_ERR != m_combo.AddString("three"));
 Thanks for explaining what happened in detail; I see your mistake.  You set the style to drop down, not drop list.  That's why you see an edit box with the cursor blinking.  Set the combo's style to drop list, and you will see the behavior you want.      As for the first line of DrawItem, I'm sorry if my comment was misleading.  lpDIS->itemData is -1 if the "edit" part is empty or the lbox is empty.  Perhaps it would be more clear to compare lpDIS->itemID to -1 instead; it works the same.
    Finally, you're right, you need a call to CDialog::OnInitDialog; I should have commented that I was leaving some of the wizard-generated stuff out.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts


The following text is addressed to Expert "nate"


It works!  How stupid of me to "forget" to set the style to DropList!  For some reason I was sure I have done it and didn't check.  Moreover, you _did_ say that setting DropList style is required.

Regardless of whether you answer the following or not I am going to grade your help as "Excelent!".

Now, I do have three more questions with regard to the method and I would like the answers from _you_, if you can kindly provide them.

My hesitation to grade your answer on the spot comes from the fact that when I do so, any other expert may "lock" my questions that follow.  Also, I won't mind increasing the points promised, since I realize there is more work to do.

Question 1.
Before my application calls DoModal to invoke the dialog, it sets a member variable, CDiscomboDlg.mode, to "enabled" or "disabled", and the combo box is to appear accordingly.  In OnInitDialog I have the following construction:

if(mode==ENABLED) {
    // invoke combo enabled
else {  //mode==DISABLED  
    // invoke combo disabled

Thanks to your help, I can now display the DISabled combo box with the text color of my choice.  

However, in case the combo is to be ENabled, I want it to behave in the standard DropList way, that is, to have the ability to scroll the selection in the combo's list with the arrow keys,
to see the selected item's text in the "selected" color, to have the "focus bar" around the selection, etc.

In other words:  How do I cause a DropList combo box that is defined in the resource editor as "Owner draw: Fixed" to appear as if defined "Owner draw: No" ?

Note:  I don't need the AddString functions, the item texts are defined in the resource editor.

Question 2
An irritating trifle:  Why does the owner draw combo appear to be a few pixels higher than defined in the resource editor?  

Note:  I could attach a tiny picture to illustrate this, but Experts Exchange doesn't allow it.

Question 3
I found that instead of doing

    m_combo.SubclassDlgItem(IDC_COMBO1, this);

in CDiscomboDlg::OnInitDialog, I might as well do

    DDX_Control(pDX, IDC_COMBO1, m_combo);  
in CDiscomboDlg::DoDataExchange and have the same results.

I don't quite realize what consequences may be implyied.
Which is the "right" way to do it?

Thank you,

1)  There are two ways - easy and hard.  The hard way is to complete DrawItem to handle all the cases.  The easy way is to put two combos on top of each other in your dialog resource and hide the one you're not going to use.

2)  IMHO, this is a bug in the combo implementation.  It is very hard to fix, i.e., I spent some time once trying to work around it and decided it was way too much effort.  Still, if you want to try, here's a start.
    Override the combo's MeasureItem and set the size you want, e.g.,

void CDisCombo::MeasureItem
{ lpMIS->itemHeight = 15; }

    In OnInitDialog, create the combo yourself (no resources) with these styles:


    Next, set the font:


    Finally, add the items manually:

int rc = m_combo.AddString("one");
rc = m_combo.AddString("two");
rc = m_combo.AddString("three");

3)  DDX_Control works because it automatically hooks up the control if the control's m_hWnd is NULL.  It calls SubclassWindow for you, so the two methods are equivalent.  I prefer the first method, though, because I think it is more clear.


I promised to Expert "nate" to increase the points (above).

When grading the last comment I did increase the points to 250, I graded "Excellent" and submitted.  Now I see that "nate" received only 200 points.

I feel very bad about this.  How do I give "nate" the 50 points that I owe him now, when my question is in the <paq> status?


Try emailing questions@experts-exchange.com.  Thanks.


I did, I also wrote to qna@experts-exchange.com.  No replies.
Here is what I'll do now --

I am going to post a new question and evaluate it to 50 points.  I'll entitle it "For nate only".  I will reject any expert that locks it, except for "nate".  When "nate" will lock the question I am going to grade it and this way "nate" will receive the 50 points that I owe him.

I hope this will outwit the Experts Exchange robot.

I take this opportunity to say that I did fully implement the methods that are described above in sections 1 and 2 and it works perfect and beautiful.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.