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






4.92/5 (45 votes)
Feb 3, 2003
5 min read

179671

6353
An theme-aware colour picker MFC control that combines the functionalities of other colour pickers on CodeProject and adds some new functionality.
- Download demo executable (MFC7) - 30 Kb
- Download demo executable (MFC6) - 28 Kb
- Download demo project - 55 Kb
- Download source - 31 Kb
![]() 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:
- Copy the five files into your project directory and add them to your project.
- Add a button to your dialog and add a variable using the Class Wizard.
- Add
#include "ColourPickerXP.h"
in your dialog's header file. - In the button definition, turn
CButton
intoCColourPickerXP
. - 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
- Original
CColourPicker
control by Chris Maunder CColorButton
modification by James White- WTL color button by Tim Smith
- Theme wrapper by Pål Kristian Tønder
CMemDC
class by Keith Rule- Other people (see below in the History section)
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. |