Click here to Skip to main content
15,923,789 members
Articles / Desktop Programming / MFC
Article

Color Controls

Rate me:
Please Sign up or sign in to vote.
3.27/5 (8 votes)
14 Mar 20022 min read 101.7K   3.4K   29   11
Adding color to MFC controls

Introduction

The great article on subclassing by Chris Maunder inspired me to add to his code. Changing the color of a common control is often tricky because depending on the control different functions may need to be overridden. For example to color a CButton you must implement:

virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS)

whereas for a CEdit you must implement:

virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, 
                           LRESULT* pLResult)

And for a CStatic ...

afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor)

I often found myself overridding the OnCtlColor method in my dialog class and then using a case statement to switch among the various controls. For applications with only a few controls this method is quick and easy. But when the number of controls increases adding and removing color controls becomes cumbersome and error prone. It also places too much logic into the dialog class. The current set of classes provide basic colorization for active and disabled states along with adding color mouse-over's (thanks Chris!).

Interface

CColorButton, CColorEdit, CColorComboBox, CColorStatic are derived from CButton, CEdit, CComboBox, CStatic respectively. They also inherit from CColorControl which provides the same interface for setting the colors.

// FG is foreground color or text color
// BG is background color of control
// Hot refers to the on mouse over colors
//
void SetColors(const COLORREF FGColor,const COLORREF BGColor, 
               const COLORREF HotFGColor, const COLORREF HotBGColor);
void SetDisabledColors(const COLORREF DisabledFGColor, 
                       const COLORREF DisabledBGColor);

//
//
void SetBgColor(COLORREF cr);
void SetFgColor(COLORREF cr);
void SetHotBgColor(COLORREF cr);
void SetHotFgColor(COLORREF cr);
void SetDisabledFgColor(COLORREF cr);
void SetDisabledBgColor(COLORREF cr);

//
// Time is in milliseconds and dictates the delay after the mouse
// leaves the rect of the control. The default is 10 milliseconds.
//
void SetRolloverDelay(UINT mSeconds );

Usage

After the control(s) are put into the dialog editor.

Image 1

Simply declare member variables in the class wizard. Make sure to include the control subclasses and rebuild or else the new class might not appear in the variable type combo.

Image 2

Now in the OnInitDialog function of you main dialog or the OnCreate function of your CWnd set the desired colors for the controls.

m_btnColor.SetColors(RGB_GREEN, RGB_BLACK, RGB_WHITE, RGB_RED);
m_btnDisabled.SetDisabledColors(RGB_WHITE, RGB_BLACK);
m_btnDisabled.SetColors(RGB_RED, RGB_BLACK, RGB_RED, RGB_WHITE);
m_edtColor.SetColors(RGB_GREEN, RGB_BLUE, RGB_WHITE, RGB_RED);
m_cbColor.SetColors(RGB_BLUE, RGB_GREEN, RGB_WHITE, RGB_RED);
m_stcColor.SetColors(RGB_GREEN, RGB_BLUE, RGB_WHITE, RGB_RED);

Image 3

Conclusion

That's all there is to it. These set of classes should provide you with an easy way to add color to your controls without having to implement any drawing or message callback functions. If you just want the color controls without the mouse overs you could make the HotFGColor the same as the FGColor and the HotBGColor the same as the BGColor.

History

15 Mar 2002 - updated downloads.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionIs there a fix for Read-Only, yet? Pin
weirdog2-Jan-09 5:38
weirdog2-Jan-09 5:38 
QuestionMemory Leak??? Pin
alan herr7-Dec-07 19:49
sussalan herr7-Dec-07 19:49 
Questionif combox is disable,it's color is not change Pin
tommy790729@126.com24-Dec-06 22:13
tommy790729@126.com24-Dec-06 22:13 
GeneralNewlines on button Pin
jojo722-Sep-03 23:16
jojo722-Sep-03 23:16 
GeneralRadio Button not available Pin
Gary Hasman18-Sep-02 4:30
Gary Hasman18-Sep-02 4:30 
GeneralFlicker fix Pin
Jack Handy27-Mar-02 23:43
Jack Handy27-Mar-02 23:43 
Very nice control. I modified the CColorButton code a little bit. I changed the OnMouseMove and OnTimer functions because I had a problem where if you clicked the button and held down your mouse button and moved the mouse around it would keep repainting and flicker badly (I also had the Hot colors set to different values than the normal colors). Anyways here is my modified OnMouseMove and OnTimer functions if anyone is interested:

void CColorButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	CPoint p(GetMessagePos());
	ScreenToClient(&p);
	CRect rect;
	GetClientRect(rect);
	if (m_bOverControl != rect.PtInRect(p)) {
		m_bOverControl = !m_bOverControl;
		Invalidate();
		SetTimer(m_nTimerID, m_iRolloverDelay, NULL);
	}
	CButton::OnMouseMove(nFlags, point);
}

void CColorButton::OnTimer(UINT nIDEvent) {
	CPoint p(GetMessagePos());
	ScreenToClient(&p);
	CRect rect;
	GetClientRect(rect);
	if (m_bOverControl != rect.PtInRect(p)) {
		m_bOverControl = !m_bOverControl;
		KillTimer(m_nTimerID);
		Invalidate();
	}
	CButton::OnTimer(nIDEvent);
}


I also tried to eliminate the need for the timer by using SetCapture() and ReleaseCapture() however that caused another problem which was that when you clicked the button held the mouse down and moved out of the button rect, when you moved back in the button rect with the mouse still down it didn't know for some reason. The 'normal' behavior would make the button appear pressed in again and if you let your mouse go at that time it will trigger the OnYourButton event.

Thanks for the code,

Jack

To an optimist the glass is half full.
To a pessimist the glass is half empty.
To a programmer the glass is twice as big as it needs to be.
GeneralMultiLine Edit doesn't work(-) Pin
Yury Goltsman16-Mar-02 23:39
Yury Goltsman16-Mar-02 23:39 
GeneralRead Only problem Pin
Mark Donkers9-Mar-02 17:08
Mark Donkers9-Mar-02 17:08 
GeneralRe: Read Only problem Pin
Paul J. Weiss12-Mar-02 3:24
Paul J. Weiss12-Mar-02 3:24 
GeneralRe: Read Only problem Pin
Mark Donkers2-Apr-02 3:25
Mark Donkers2-Apr-02 3:25 
GeneralNice Job but i got one comment Pin
24-Feb-02 7:28
suss24-Feb-02 7:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.