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
into
CColourPickerXP
.
- 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. |