Click here to Skip to main content
15,881,413 members
Articles / Desktop Programming / MFC
Article

CColourPickerXP - a Theme-aware Colour Picker with 2 Styles.

Rate me:
Please Sign up or sign in to vote.
4.92/5 (47 votes)
1 Jul 20035 min read 176.3K   6.3K   75   43
An theme-aware colour picker MFC control that combines the functionalities of other colour pickers on CodeProject and adds some new functionality.

Button style

 

 


ComboBox style


And of course, classic style...

Introduction

Recently, I needed a colour picker for a project. I found three articles on CodeProject on which I based my own control :

Because I needed a theme-aware MFC control, none of these were fully satisfying. So I decided to create my own control with the following features:

  • XP Theme support
  • 2 styles : button and combo-box.
  • Store the 16 custom colours in the registry. Also available in static version.
  • Load colour names from resources.
  • (only combo-box style) Show RGB-values.
  • Subclassing possibilities (virtual draw functions).
  • Use of memory DC to prevent flickering.

For the theme support, I used the CXPTheme class of Pål Kristian Tønder. The memory DC was implemented thanks to the CMemDC class of Keith Rule.

Using the code

To use this control, follow these steps:

  1. Copy the five files into your project directory and add them to your project.
  2. Add a button to your dialog and add a variable using the Class Wizard.
  3. Add #include "ColourPickerXP.h" in your dialog's header file.
  4. In the button definition, turn CButton into CColourPickerXP.
  5. You can modify the parameters of the picker int the OnInitDialog function of the dialog's class.

To enable multi-monitor support, you'll need to set the WINVER macro in stdafx.h to at least 0x0500.

Properties and functions

__declspec(property(get=GetColor,put=SetColor)) COLORREF Color;
virtual COLORREF GetColor(void) const;
virtual COLORREF GetColor(BOOL bTranslateDefault) const;
virtual void SetColor(COLORREF Color);

Get or set the active colour.
Use CLR_DEFAULT for default colour. When using GetColor(TRUE) the default colour is translated in the colour set with SetDefaultColor.

__declspec(property(get=GetDefaultColor,put=SetDefaultColor))
  COLORREF DefaultColor;
virtual COLORREF GetDefaultColor(void) const;
virtual void SetDefaultColor(COLORREF Color);

Get or set the default colour.
This colour is displayed when user selected the default colour. This colour is also returned when using GetColor(TRUE) and the user has selected the default colour.

__declspec(property(get=GetTrackSelection,put=SetTrackSelection))
  BOOL TrackSelection;
virtual BOOL GetTrackSelection(void) const;
virtual void SetTrackSelection(BOOL bTrack);

Get or toggle track selection.

__declspec(property(put=SetCustomText)) LPCTSTR CustomText;
virtual void SetCustomText(LPCTSTR tszText);

Set the text for the custom colour-box.
Default is "More Colours...".
Use "" to hide the custom colour-box.

__declspec(property(put=SetDefaultText)) LPCTSTR DefaultText;
virtual void SetDefaultText(LPCTSTR tszText);

Set the text for the default colour-box.
Default is "Automatic".
Use "" to hide the default colour-box.

__declspec(property(put=SetColoursName)) UINT ColoursName;
static void SetColoursName(UINT nFirstID = 0);

Load the names of the colours from the resources.
nFirstID is the resource ID of the first colour (= black).
If nFirstID is 0, default English names are loaded.

__declspec(property(put=SetRegSection)) LPCTSTR RegSection;
__declspec(property(put=SetRegSectionStatic)) LPCTSTR RegSectionStatic;
virtual void SetRegSection(LPCTSTR tszRegSection = _T(""));
static void SetRegSectionStatic(LPCTSTR tszRegSection = _T(""));

Set the registry section used to save the 16 custom colours of the colour selection dialog.
Use "" to disable.
If the non-static version exists, it will be used. Otherwise the static version will be used. If none are defined, the colours won't be saved.
Note : make sure (especially for dialog projects) you have set the registry key in CWinApp::InitInstance with SetRegistryKey(_T("Your registry key here"));.

__declspec(property(get=GetStyle,put=SetStyle)) BOOL Style;
virtual BOOL GetStyle(void) const;
virtual void SetStyle(BOOL bComboBoxStyle);

Get or set the style of the control : FALSE means button, TRUE means combo-box.
When switching to combo-box style, the height is set according to the text height.

__declspec(property(put=SetRGBText)) LPCTSTR RGBText;
virtual void SetRGBText(LPCTSTR tszRGB = _T("RGB"));

(combo-box style only)
Set the three letters used to display the RGB-value.
If the submitted text is less than 3 letters, the missing letters are replaced by whitespaces.

__declspec(property(get=GetAlwaysRGB,put=SetAlwaysRGB)) BOOL ShowRGBAlways;
virtual BOOL GetAlwaysRGB(void) const;
virtual void SetAlwaysRGB(BOOL bShow);

(combo-box style only)
Show RGB-value between brackets when name is known. When name isn't know (i.e. user has selected a custom colour) the RGB-value is always shown even if you've set FALSE here.

CFont* GetFont() const;
void SetFont(CFont* pFont, BOOL bRedraw = TRUE);

(combo-box style only)
Get or set the font.
The font isn't used in the pop-up.
Call SetStyle after changing font to adjust the control's height.
For more information see the corresponding functions of the CWnd class.

Messages

In order to handle the messages generated by the CColourPickerXP control, you will need to manually add message handlers to your message map :

ON_MESSAGE( Message, MessageFn)
MessageFn is of the form :
afx_msg LONG MessageFn(UINT lParam, LONG wParam);
The lParam indicates the colour, the wParam returns the Control ID.

For Message, you can choose from the following :

MessageDescription
CPN_SELCHANGEColour Picker Selection change
CPN_DROPDOWNColour Picker drop down
CPN_CLOSEUPColour Picker close up
CPN_SELENDOKColour Picker end OK
CPN_SELENDCANCELColour Picker end (cancelled)

Points of Interest

When you look at the colour buttons found in Windows XP, you'll remark some 'imperfections':

  • There is no hover support.
  • The focus rectangle is not placed very well.
  • The pop-up uses the old Windows 95 style.
  • Sometimes, you can see a nasty border. I had the same problem, but solved it by sending a WM_ERASEBKGND message with the memory DC as parameter.

Acknowledgments

History

VersionDetails
version 1.4Fixed : "A required resource was"-dialog due to not restoring the DC after drawing pop-up (thanks to Kris Wojtas, KRI Software).
Using old style selection rectangle in pop-up when flat menus are disabled.
Pop-up will now raise when user hit F4-key or down-arrow.
Modified : moving around in the pop-up with arrow keys when no colour is selected.
version 1.3Parent window now stays active when popup is up on screen (thanks to Damir Valiulin).
When using track-selection, the initial colour is shown for an invalid selection instead of black.
Added : bTranslateDefault parameter in GetColor.
version 1.2Fixed : in release configuration, with neither 'Automatic' nor 'Custom' labels, the pop-up won't work.
Disabled combo-box is now drawn correctly.
Combo-box's height now depends on text size.
Font support : use SetFont and GetFont, for combo-box style call SetStyle after changing font.
version 1.1Fixed some compile errors in VC6.
No need anymore to change the defines in stdafx.h except for multi-monitor support.
version 1.0First release.

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
Belgium Belgium
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNot working at VS 2008 Pin
woohmh16-Mar-09 15:02
woohmh16-Mar-09 15:02 
GeneralRe: Not working at VS 2008 Pin
Gizi Gyorgy19-Nov-09 0:04
Gizi Gyorgy19-Nov-09 0:04 
GeneralLevel 4 warnings in Visual Studio 2003 Pin
Warren Stevens4-Jan-07 6:54
Warren Stevens4-Jan-07 6:54 
GeneralAnother small fix if used on secondary monitor Pin
jefflewis4-Sep-06 1:59
jefflewis4-Sep-06 1:59 
GeneralRe: Another small fix if used on secondary monitor Pin
DaveWH7-Sep-06 8:22
DaveWH7-Sep-06 8:22 
GeneralCOLORREF Pin
Dody_DK30-Nov-05 12:05
Dody_DK30-Nov-05 12:05 
GeneralAn suggestion to improve independence of CColourPickerXP class! Do NOT use custom message! Pin
Behzad Ebrahimi27-Feb-05 3:59
Behzad Ebrahimi27-Feb-05 3:59 
GeneralRe: An suggestion to improve independence of CColourPickerXP class! Do NOT use custom message! Pin
Anonymous16-May-05 18:22
Anonymous16-May-05 18:22 
AnswerRe: An suggestion to improve independence of CColourPickerXP class! Do NOT use custom message! Pin
Behzad Ebrahimi19-Sep-05 5:34
Behzad Ebrahimi19-Sep-05 5:34 
GeneralMultiple Monitor bug Pin
Don Kackman11-Jun-04 5:15
Don Kackman11-Jun-04 5:15 
GeneralRe: Multiple Monitor bug Pin
Don Kackman14-Jun-04 5:24
Don Kackman14-Jun-04 5:24 
GeneralNice Control Pin
Don Kackman5-Jun-04 16:36
Don Kackman5-Jun-04 16:36 
GeneralRe: Nice Control Pin
Zorglab5-Jun-04 23:45
Zorglab5-Jun-04 23:45 
GeneralRe: Nice Control Pin
sanjit_rath4-Nov-04 14:07
sanjit_rath4-Nov-04 14:07 
GeneralSmall unicode fix Pin
Abraxas2315-Apr-04 20:44
Abraxas2315-Apr-04 20:44 
Generalobscure visual problem Pin
Ing-Long Eric Kuo16-Sep-03 20:48
Ing-Long Eric Kuo16-Sep-03 20:48 
GeneralRe: obscure visual problem Pin
tmancey30-Mar-06 2:03
tmancey30-Mar-06 2:03 
AnswerRe: obscure visual problem Pin
awicons24-Jul-09 1:07
awicons24-Jul-09 1:07 
GeneralPlug and play Pin
Tocap25-Jun-03 9:54
Tocap25-Jun-03 9:54 
GeneralRe: Plug and play Pin
Zorglab27-Jun-03 5:40
Zorglab27-Jun-03 5:40 
GeneralA required resource was Pin
Kris Wojtas2-Jun-03 3:27
Kris Wojtas2-Jun-03 3:27 
GeneralRe: A required resource was Pin
Zorglab27-Jun-03 5:39
Zorglab27-Jun-03 5:39 
GeneralGood , and ask a question Pin
Marquis.D.J13-Apr-03 16:25
Marquis.D.J13-Apr-03 16:25 
GeneralRe: Good , and ask a question Pin
Zorglab15-Apr-03 8:57
Zorglab15-Apr-03 8:57 
Questiontoo many CPN_SELCHANGE event? Pin
grayra28-Mar-03 2:52
grayra28-Mar-03 2:52 

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.