Click here to Skip to main content
13,253,507 members (62,867 online)
Click here to Skip to main content
Add your own
alternative version


24 bookmarked
Posted 9 Apr 2008

XColorPickerXP - an MFC color picker control with themed look

, 9 Apr 2008
Rate this:
Please Sign up or sign in to vote.
XColorPickerXP is a simple drop-in color picker based on CComboBox that pops up color selection grid.


For many years I have been using my XColourPicker control, which I based on Chris Maunder's excellent color picker control. Recently my project manager asked me why I wasn't using a control with a modern look. That's when I realized that my control still had the flat Windows 2000 look, even when used in a themed app:


To make this look good in a themed app, I knew I had to add support for visual themes, which has always involved a good deal of effort whenever I tried it. Nevertheless, I decided to look into it. What I discovered was something unexpected that completely surprised me.

Comboboxes and Themes

In trying to decide how to proceed, it struck me that the color picker has the appearance of a combobox, rather than a button (my XColourPicker control is derived from CButton). Because of this, my XColourPicker control needed code to position and draw the down arrow, and a lot of other details to make it look like a combobox.

But what if I started from CComboBox? Could I eliminate some of the drawing code? To investigate this possibility, I started by creating a new class derived from CComboBox. I added the virtual DrawItem() function, which the framework calls for ownerdraw controls. Then I made sure the combobox in the demo was marked as ownerdraw. When I tried the demo app, I was amazed. Without using any of the uxtheme functions at all, the combobox was drawn using visual themes, even though it was marked as ownerdraw. Mouse hover also worked, changing the appearance to hot state. And I did not have to do anything to achieve this!

Naturally this made the job much easier. I added code to DrawItem() to draw a color-filled rect, and I was done.

Here is what the demo app for the new control looks like:


XColorPickerXP API

The programmatic interface to XColorSpectrumCtrl attributes is very simple: just six functions to get/set color and custom colors.

COLORREF GetColor() Retrieves RGB color value
void GetCustomColors(COLORREF * pCustomColors) Retrieves array of 16 custom color RGB values
CString GetCustomColors() Retrieves 16 custom colors as space-separated string of RGB values
CXColorPickerXP& SetColor(COLORREF crColor) Sets color from RGB value
CXColorPickerXP& SetCustomColors(COLORREF * pCustomColors) Sets 16 custom colors from array of RGB values
CXColorPickerXP& SetCustomColors(LPCTSTR lpszCustomColors) Sets 16 custom colors from space-separated string of RGB values

XColorPickerXP DDX Helpers

XColorPickerXP provides two DDX helper functions:
// get/set color value
void AFXAPI DDX_XColorPickerXP(CDataExchange * pDX, int nIDC, COLORREF& crColor);

// get/set custom colors from string of space-separated color values
void AFXAPI DDX_XColorPickerXPCustom(CDataExchange * pDX, int nIDC, CString& strCustomColors);
In the demo app, these functions are used in DoDataExchange() function:
void CXColorPickerXPTestDlg::DoDataExchange(CDataExchange* pDX)
    DDX_Control(pDX, IDC_COLOR_SAMPLE, m_stcColorSample);
    DDX_Control(pDX, IDC_BACKGROUND_COLOR, m_ctlBackgroundColor);
    DDX_Control(pDX, IDC_TEXT_COLOR, m_ctlTextColor);

    DDX_XColorPickerXP(pDX, IDC_TEXT_COLOR, m_rgbText);
    DDX_XColorPickerXP(pDX, IDC_BACKGROUND_COLOR, m_rgbBackground);

    DDX_XColorPickerXPCustom(pDX, IDC_TEXT_COLOR, m_strTextCustomColors);
    DDX_XColorPickerXPCustom(pDX, IDC_BACKGROUND_COLOR, m_strBackgroundCustomColors);

How To Use

To integrate XColorPickerXP into your app, you first need to add following files to your project:

  • XColorPickerXP.cpp
  • XColorPickerXP.h
  • XColorPopupXP.cpp
  • XColorPopupXP.h

Then use resource editor to add combobox control to your dialog, and use Class Wizard to attach member variable to that control.

Next, include header file XColorPickerXP.h in the dialog's header file. Then replace the CComboBox definition with CXColorPickerXP. Now you are ready to start using XColorPickerXP.

Demo App

The demo dialog processes color changes in the OnColorChange handler:
LRESULT CXColorPickerXPTestDlg::OnColorChange(WPARAM, LPARAM lParam)
    TRACE(_T("in CXColorPickerXPTestDlg::OnColorChange\n"));

    if (lParam == IDC_TEXT_COLOR)
    else if (lParam == IDC_BACKGROUND_COLOR)

    if (m_ctlTextColor.GetColor() == m_ctlBackgroundColor.GetColor())
        CXBalloonMsg::Show(_T("Unreadable Colors"),
                           _T("The text and background colors are identical.\r\n")
                           _T("The text will not be readable."),
        m_rgbText = m_ctlTextColor.GetColor();
        m_rgbBackground = m_ctlBackgroundColor.GetColor();


    return 0;

Revision History

Version 1.0 - 2008 April 9

  • Initial public release.


This software is released into the public domain. You are free to use it in any way you like, except that you may not sell this source code. If you modify it or extend it, please to consider posting new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Hans Dietrich
Software Developer (Senior) Hans Dietrich Software
United States United States
I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.

Recently, I have moved to Los Angeles where I am doing consulting and development work.

For consulting and custom software development, please see

You may also be interested in...


Comments and Discussions

QuestionQuestion on use Pin
DavidCrow24-Feb-12 4:43
memberDavidCrow24-Feb-12 4:43 
GeneralProblem in my vc2010 [modified] Pin
niils6-Oct-10 5:24
memberniils6-Oct-10 5:24 
GeneralRe: Problem in my vc2010 Pin
Hans Dietrich6-Oct-10 6:09
mentorHans Dietrich6-Oct-10 6:09 
Thanks for the kind words.

niils wrote:
in my version 2010, XColorPopupXP.cpp(line 622), SystemParametersInfo cannot run

This problem is caused by a change to the NONCLIENTMETRICS struct:
typedef struct tagNONCLIENTMETRICSA
    UINT    cbSize;
    int     iBorderWidth;
    int     iScrollWidth;
    int     iScrollHeight;
    int     iCaptionWidth;
    int     iCaptionHeight;
    LOGFONTA lfCaptionFont;
    int     iSmCaptionWidth;
    int     iSmCaptionHeight;
    LOGFONTA lfSmCaptionFont;
    int     iMenuWidth;
    int     iMenuHeight;
    LOGFONTA lfMenuFont;
    LOGFONTA lfStatusFont;
    LOGFONTA lfMessageFont;
#if(WINVER >= 0x0600)
    int     iPaddedBorderWidth;
#endif /* WINVER >= 0x0600 */

As you can see, the new iPaddedBorderWidth is added when WINVER is 0x0600 (Vista) or greater. This is fine for Vista, but using this on an earlier OS will cause SystemParametersInfo() to fail.

My solution is to do this:
        UINT    cbSize;
        int     iBorderWidth;
        int     iScrollWidth;
        int     iScrollHeight;
        int     iCaptionWidth;
        int     iCaptionHeight;
        LOGFONT lfCaptionFont;
        int     iSmCaptionWidth;
        int     iSmCaptionHeight;
        LOGFONT lfSmCaptionFont;
        int     iMenuWidth;
        int     iMenuHeight;
        LOGFONT lfMenuFont;
        LOGFONT lfStatusFont;
        LOGFONT lfMessageFont;
    const UINT cbProperSize = sizeof(OLD_NONCLIENTMETRICS);
    ncm.cbSize = cbProperSize;
#ifdef _DEBUG
    BOOL ok = 
    ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, cbProperSize, &ncm, 0);
    TRACE(_T("message font=<%s>\n"), ncm.lfMessageFont.lfFaceName);

You can also play around with WINVER and set it to some value less than 0x600, but this has its own problems.
Best wishes,

[Hans Dietrich Software]

GeneralPopup is not themed Pin
Damir Valiulin23-Apr-08 17:23
memberDamir Valiulin23-Apr-08 17:23 
GeneralRe: Popup is not themed Pin
theCPkid4-Nov-08 19:53
membertheCPkid4-Nov-08 19:53 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 9 Apr 2008
Article Copyright 2008 by Hans Dietrich
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid