Combobox Color Picker

I recently wanted to allow certain color selection in one of my projects. The common control available is a great thing but I wanted the look-and-feel of something similar to what VC++ offers in its options dialog box. The following code acomplishes exactly that.

Just include the ComboColorPicker.h and ComboColorPicker.cpp files in your project and create a control member variable for a regular combobox in VC's classwizard and you have your self a combobox for color selection. This combobox implements focus indication correctly but still lacks the [Automatic] option VC has.

ComboColorPicker.h

#if !defined(AFX_COMBOCOLORPICKER_H__B2348841_5541_11D1_8756_
   00A0C9181E86__INCLUDED_)
#define AFX_COMBOCOLORPICKER_H__B2348841_5541_11D1_8756_
   00A0C9181E86__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif    // _MSC_VER >= 1000
// ComboColorPicker.h : header file
// © 1997 Baldvin Hansson

///////////////////////////////////////////////////////////////////
// CComboColorPicker window

class CComboColorPicker : public CComboBox
{
// Construction
public:
   CComboColorPicker();

// Attributes
private:
   bool m_bInitialized;
   static COLORREF m_rgStandardColors[];
public:

// Operations
private:
   void InitializeData();
public:
   COLORREF GetSelectedColor();

// Overrides
   // ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(CComboColorPicker)
   protected:
   virtual void PreSubclassWindow();
   //}}AFX_VIRTUAL
   virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

// Implementation
public:
   virtual ~CComboColorPicker();

   // Generated message map functions
protected:
   //{{AFX_MSG(CComboColorPicker)
   int OnCreate(LPCREATESTRUCT lpCreateStruct);
   //}}AFX_MSG

   DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations
// immediately before the previous line.

#endif // !defined(AFX_COMBOCOLORPICKER_H__B2348841_5541_11D1_
       //          8756_00A0C9181E86__INCLUDED_)

ComboColorPicker.cpp

// ComboColorPicker.cpp : implementation file
// © 1997 Baldvin Hansson

#include "stdafx.h"
#include "ComboColorPicker.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////
// CComboColorPicker

COLORREF CComboColorPicker::m_rgStandardColors[] = {
   RGB(0, 0, 0),            // Black
   RGB(255, 255, 255),      // White
   RGB(128, 0, 0),          // Dark Red
   RGB(0, 128, 0),          // Dark Green
   RGB(128, 128, 0),        // Dark Yellow
   RGB(0, 0, 128),          // Dark Blue
   RGB(128, 0, 128),        // Dark Magenta
   RGB(0, 128, 128),        // Dark Cyan
   RGB(192, 192, 192),      // Light Grey
   RGB(128, 128, 128),      // Dark Grey
   RGB(255, 0, 0),          // Red
   RGB(0, 255, 0),          // Green
   RGB(255, 255, 0),        // Yellow
   RGB(0, 0, 255),          // Blue
   RGB(255, 0, 255),        // Magenta
   RGB(0, 255, 255),        // Cyan
   };

CComboColorPicker::CComboColorPicker()
{
   m_bInitialized = false;
}

CComboColorPicker::~CComboColorPicker()
{
}


BEGIN_MESSAGE_MAP(CComboColorPicker, CComboBox)
   //{{AFX_MSG_MAP(CComboColorPicker)
   ON_WM_CREATE()
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////
// CComboColorPicker message handlers

int CComboColorPicker::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CComboBox::OnCreate(lpCreateStruct) == -1)
      return -1;

   InitializeData();

   return 0;
}

void CComboColorPicker::PreSubclassWindow()
{
   InitializeData();

   CComboBox::PreSubclassWindow();
}

void CComboColorPicker::InitializeData()
{
   int nItem;

   if (m_bInitialized)
      return;

   for (int nColor = 0; nColor < sizeof(m_rgStandardColors)/
        sizeof(COLORREF); nColor++)
   {
      // Here we could affect the sort order at run-time
      nItem = AddString((LPCTSTR)m_rgStandardColors[nColor]);

      if (CB_ERRSPACE == nItem)
         break;
   }

   m_bInitialized = true;
}

void CComboColorPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
   CDC dc;
   CBrush brushBlack;
   brushBlack.CreateStockObject(BLACK_BRUSH);

   if (!dc.Attach(lpDrawItemStruct->hDC))
      return;

   COLORREF rgbTextColor = dc.GetTextColor();
   COLORREF rgbBkColor   = dc.GetBkColor();

   if (lpDrawItemStruct->itemAction & ODA_FOCUS)
   {
      dc.DrawFocusRect(&lpDrawItemStruct->rcItem);
   }
   else if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)
   {
      if (lpDrawItemStruct->itemState & ODS_FOCUS)
         dc.DrawFocusRect(&lpDrawItemStruct->rcItem);
      else
         dc.ExtTextOut(0, 0, ETO_OPAQUE, &lpDrawItemStruct->rcItem,
                       _T(""), 0, NULL);
   }

   if (0 <= (int)lpDrawItemStruct->itemID)    // Any item selected?
   {
      ::InflateRect(&lpDrawItemStruct->rcItem, -2, -2);

      dc.FillSolidRect(&lpDrawItemStruct->rcItem,
                       (COLORREF)lpDrawItemStruct->itemData);
      dc.FrameRect(&lpDrawItemStruct->rcItem, &brushBlack);
   }

   // Restore the DC state
   dc.SetTextColor(rgbTextColor);
   dc.SetBkColor(rgbBkColor);
   dc.Detach();
}

COLORREF CComboColorPicker::GetSelectedColor()
{
   int nItem = GetCurSel();
   if (CB_ERR == nItem)
      return RGB(0, 0, 0);    // Default to black if nothing is selected

   return m_rgStandardColors[nItem];
}


Comments

  • http://clubpro.spb.ru

    Posted by Legacy on 01/03/2003 12:00am

    Originally posted by: Konstantin Ermakov

    Hi!

    Some additional comments. Platform is not specified,
    so under Win2K it does not work.

    1. In the resources you should specify the "Owner draw", "contain strings"

    2. Use the following code in the DrawItem(...)
    if (0 <= (int)lpDrawItemStruct->itemID) // Any item selected?
    {
    COLORREF color = m_stdColors[ (int)lpDrawItemStruct->itemID ];
    ::InflateRect(&lpDrawItemStruct->rcItem, -2, -2);

    dc.FillSolidRect(&lpDrawItemStruct->rcItem, color);
    dc.FrameRect(&lpDrawItemStruct->rcItem, &brushBlack );
    }

    ....
    then it's fine.

    See you!

    Reply
  • add ... virtual MeasureItem(...)

    Posted by Legacy on 07/12/2002 12:00am

    Originally posted by: Yong Kyu

    miss virtual MeasureItem(..)

    CColorComboEx::MeasureItem(Lp...){


    }

    Reply
  • C:\DEV-C_~1\BIN\windres: C:\\MYDOCU~1\\RSRC.RC:2: parse error?

    Posted by Legacy on 11/19/2001 12:00am

    Originally posted by: Michael Barry

    Whenever I try to add this to my code it says C:\DEV-C_~1\BIN\windres: C:\\MYDOCU~1\\RSRC.RC:2: parse error. I don't know why,please email me with help!!!

    Reply
  • Error in implementation

    Posted by Legacy on 08/04/2000 12:00am

    Originally posted by: Alexey Serov

    This string gives me an eror while runtime:
    nItem = AddString((LPCTSTR)m_rgStandardColors[nColor]);
    I changed it to
    AddString("");
    nItem = SetItemData(nColor, m_rgStandardColors[nColor]);
    It works. Is it right?

    Reply
  • Confused about implementation

    Posted by Legacy on 01/03/2000 12:00am

    Originally posted by: Dan Waters

    I created a control member variable... so now in my header it says
    
    

    CComboBox m_box;

    What do I need to do with m_box to make it a color picker?

    -D

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • A global data storage provider whose business is booming needed a best-in-class data center to serve as the backbone of its technical operations going forward—and it needed it delivered within a year.

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds