Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

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

0.00/5 (No votes)
1 Jul 2003 1  
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 :

Message Description
CPN_SELCHANGE Colour Picker Selection change
CPN_DROPDOWN Colour Picker drop down
CPN_CLOSEUP Colour Picker close up
CPN_SELENDOK Colour Picker end OK
CPN_SELENDCANCEL Colour 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

Version Details
version 1.4 Fixed : "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.3 Parent 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.2 Fixed : 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.1 Fixed some compile errors in VC6.
No need anymore to change the defines in stdafx.h except for multi-monitor support.
version 1.0 First 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