Combobox Color Picker
Posted
by Baldvin Hansson
on October 19th, 1998
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:00amOriginally 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:00amOriginally 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:00amOriginally 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!!!
ReplyError in implementation
Posted by Legacy on 08/04/2000 12:00amOriginally posted by: Alexey Serov
This string gives me an eror while runtime:
ReplynItem = AddString((LPCTSTR)m_rgStandardColors[nColor]);
I changed it to
AddString("");
nItem = SetItemData(nColor, m_rgStandardColors[nColor]);
It works. Is it right?
Confused about implementation
Posted by Legacy on 01/03/2000 12:00amOriginally posted by: Dan Waters
Reply