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

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • Email is the most common communication vehicle used by organizations of all shapes and sizes. Among the billions of email messages sent every day are sensitive information, critical requests, and other essential business data. IT staff bear the burden of ensuring the confidentiality, integrity, and availability of the information contained within the communication. This white paper explores the email security landscape, an assessment of the threats organizations face,  and the building blocks of an effective …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds