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

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • It's not unusual for a company to use a variety of formal and informal file-sharing methods. Many methods are fraught with significant operational, financial, and legal risks in addition to other potentially negative business consequences. Strategic managed file transfer (MFT) software and services help connect the business "dots" between the various ad hoc and more systematic ways that files are moved. Read this white paper to learn how the right MFT solution, can bring order, structure, and, importantly, …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds