Click here to Skip to main content
15,886,071 members
Articles / Desktop Programming / MFC
Article

XColorPickerXP - an MFC color picker control with themed look

Rate me:
Please Sign up or sign in to vote.
4.13/5 (7 votes)
9 Apr 2008CPOL3 min read 44K   1.5K   25   5
XColorPickerXP is a simple drop-in color picker based on CComboBox that pops up color selection grid.

Introduction

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:

screenshot

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:

screenshot

XColorPickerXP API

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

FunctionDescription
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)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CXColorPickerXPTestDlg)
    DDX_Control(pDX, IDC_COLOR_SAMPLE, m_stcColorSample);
    DDX_Control(pDX, IDC_BACKGROUND_COLOR, m_ctlBackgroundColor);
    DDX_Control(pDX, IDC_TEXT_COLOR, m_ctlTextColor);
    //}}AFX_DATA_MAP

    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)
    {
        TRACE(_T("IDC_TEXT_COLOR\n"));
    }
    else if (lParam == IDC_BACKGROUND_COLOR)
    {
        TRACE(_T("IDC_BACKGROUND_COLOR\n"));
    }

    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_ctlBackgroundColor.m_hWnd, 
                           m_hWnd,
                           AfxGetInstanceHandle(),
                           TTI_ERROR);
    }
    else
    {
        m_rgbText = m_ctlTextColor.GetColor();
        m_rgbBackground = m_ctlBackgroundColor.GetColor();
    }

    m_ctlTextColor.SetColor(m_rgbText);
    m_ctlBackgroundColor.SetColor(m_rgbBackground);
    m_stcColorSample.SetTextColor(m_rgbText);
    m_stcColorSample.SetBackgroundColor(m_rgbBackground);

    return 0;
}

Revision History

Version 1.0 - 2008 April 9

  • Initial public release.

Usage

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.

License

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


Written By
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 www.hdsoft.org.






Comments and Discussions

 
QuestionQuestion on use Pin
David Crow24-Feb-12 3:43
David Crow24-Feb-12 3:43 
Great article, Hans. How to go about using CXColorPopupXP::m_crColors to get the name of the selected color? I know the color name shows up when hovering over the control, but I'd also like to store the selected color name elsewhere.

"One man's wage rise is another man's price increase." - Harold Wilson

"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous



modified 24-Feb-12 14:17pm.

GeneralProblem in my vc2010 [modified] Pin
wiils6-Oct-10 4:24
wiils6-Oct-10 4:24 
GeneralRe: Problem in my vc2010 Pin
Hans Dietrich6-Oct-10 5:09
mentorHans Dietrich6-Oct-10 5:09 
GeneralPopup is not themed Pin
Damir Valiulin23-Apr-08 16:23
Damir Valiulin23-Apr-08 16:23 
GeneralRe: Popup is not themed Pin
theCPkid4-Nov-08 18:53
theCPkid4-Nov-08 18: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.