Click here to Skip to main content
15,917,645 members
Please Sign up or sign in to vote.
3.50/5 (2 votes)
See more:
By using MFC, I create 3 combo boxes on CDialog. One is color combobox and the other two are just number comboboxes. While creating color combobox, I added ON_WM_CTLCOLOR() on CDialog Class and wrote color changed function there. Now, color comboxbox is working well. But when choosing color from color from color combobox, other comboboxes colors are also changed. I don't want to change the color of other comboboxes.

Suppose, color combobox control is IDC_COLOR_COMBO. And I check in ON_WM_CTLCOLOR() as:

C++
if (nCtlColor == CTLCOLOR_EDIT || nCtlColor == CTLCOLOR_LISTBOX && pWnd->GetDlgCtrlID() == IDC_COLOR_COMBO) { //change color; }


Even though, I write as above, it still changes the color of other combo boxes. I don't know where and how can I control it.
Could you please provide me solution for my problem?
Thanks in advanced.
Posted
Updated 9-Mar-11 8:38am
v5

If this "if" statement is from your real code, then your troubles are there.
Lets first use PRE tags and have a look at your "if" statement:
C++
if (nCtlColor == CTLCOLOR_EDIT || nCtlColor == CTLCOLOR_LISTBOX && pWnd->GetDlgCtrlID() == IDC_COLOR_COMBO) 
{ 
    //change color; 
}


Now examine the condition block in your "if" statement and keep in mind that the AND operator (&&) will be evaluated before the OR operator (||), because of it's higher priority[^].

I'm pretty sure that the correct way of writing this "if" statement is this (with additional brackets to guarantee that the OR operator (||) will be evaluated first):
C++
if ((nCtlColor == CTLCOLOR_EDIT || nCtlColor == CTLCOLOR_LISTBOX) && pWnd->GetDlgCtrlID() == IDC_COLOR_COMBO) 
{ 
   //change color; 
}


Also consider deriving a class from CComboBox and use the reflection of WM_CTLCOLOR in order to have your own colored one.
You can subclass even the list control and the edit control parts of the combobox. Check it out here[^].

I hope this helps. :)


[Update]

It seems that there is an interesting behavior of WM_CTLCOLOR with combobox. Have e look at this[^] discussion.

IMHO the best option is deriving your own class from CComboBox. It could be really very simple.

Have a look at this demo class that I've created as an example for you:

- Relevant part from ColorCombo.h:
class CColorCombo : public CComboBox
{
	DECLARE_DYNAMIC(CColorCombo)
public:
	CColorCombo();
	virtual ~CColorCombo();

protected:
	DECLARE_MESSAGE_MAP()

public:
        // We will trap WM_CTLCOLOR directly...
	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
};


- Relevant part from the ColorCombo.cpp:
IMPLEMENT_DYNAMIC(CColorCombo, CComboBox)

CColorCombo::CColorCombo()
{
}

CColorCombo::~CColorCombo()
{
}

BEGIN_MESSAGE_MAP(CColorCombo, CComboBox)
	ON_WM_CTLCOLOR()  // WM_CTLCOLOR message map entry
END_MESSAGE_MAP()

// And here is an example code for OnCtlColor
HBRUSH CColorCombo::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);

	// Just a demo...
	if (nCtlColor == CTLCOLOR_EDIT || nCtlColor == CTLCOLOR_LISTBOX) 
	{
                // For example we can set text and etc.
		pDC->SetTextColor(RGB(255, 0, 0));
		pDC->SetBkMode(TRANSPARENT);

                // If you need to color the background you can return a brush 
                // different from 'hbr'. Because this is just a demonstration 
                // I'll create the brush here but keep in mind that creating brush 
                // once and keeping it for example as a class member is better approach.
		return (HBRUSH) ::CreateSolidBrush(RGB(255, 255, 0));
	}

	return hbr;
}


Now in your dialog class you can add member for your combo box, include ColorCombo.h and change the added member type from CComboBox to CColorCombo - that's it! :)

An alternative approach is subclassing the combo box. See here[^] for details, but I still recommend deriving your own class from CComboBox as I've already demonstrated this method. IMHO this is the clearest approach. :)

[/Update]
 
Share this answer
 
v5
Comments
April2004 9-Mar-11 11:39am    
I'd already tried with "if" condition that you mentioned. But it doesn't work. For dropdown style, owner drawn fixed combo box, nCtlColr is equal to CTLCOLOR_EDIT. Am I right? Then, even though I don't know the reason, pWnd->GetDlgCtrlID() is not equal to IDC_COLOR_COMBO. So, that condition is never true and with above mentioned "if" condition, color combo box also doesn't work.

Thank you for your suggestion. I am still finding the solution now. If you have other idea, please let me know. With Regards..
Nuri Ismail 9-Mar-11 12:59pm    
Please have a look at my updated answer.
April2004 10-Mar-11 9:55am    
My problem is solved by your updated answer. Thank you very much for your updated answer. ^^
Nuri Ismail 10-Mar-11 10:45am    
I'm glad it helped. You are welcome! :)
if i understood your question correctly the simple answer is that you cannot since your changing the color of the general theme of your application. This is like when you change the display settings on your computer they will apply to all the windows.
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900