使用前,请将控件的Style属性设置为DropdownList(下拉列表),Owner Draw设置为Fixed,Has Strings设置为TRUE,效果图如下:
头文件声明(CSWColorComboBox.h):
#pragma once
#include "afxwin.h"
#include <afxcmn.h>
class CSWColorComboBox :
public CComboBox
{
DECLARE_DYNAMIC(CSWColorComboBox)
#define MAX_COLOR_COUNT 16
#define MAX_COLOR_NAME 16
struct TColorProperty
{
COLORREF m_clrColor;
char m_szName[MAX_COLOR_NAME];
TColorProperty()
{
memset(this, 0, sizeof(TColorProperty));
};
TColorProperty(COLORREF color, LPCTSTR lpszName)
: TColorProperty()
{
m_clrColor = color; // 颜色值
strncpy_s(m_szName, lpszName, MAX_COLOR_NAME); // 颜色名称
};
};
public:
CSWColorComboBox();
virtual ~CSWColorComboBox();
private:
static TColorProperty s_clrPropertys[MAX_COLOR_COUNT]; // WEB标准颜色数组
private:
void CommonConstruct(); // 初始化
protected:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void PreSubclassWindow();
protected:
DECLARE_MESSAGE_MAP()
public:
// 获取选择色彩值
COLORREF GetSelColor();
// 选择色彩项
void SelectColor(COLORREF color);
void SelectColor(LPCTSTR lpszName);
// 删除色彩项
void DeleteColor(LPCTSTR lpszName);
void DeleteColor(COLORREF color);
// 添加色彩项
int AddColor(LPCTSTR lpszName, COLORREF color);
};
源码实现(CSWColorComboBox.cpp):
#include "stdafx.h"
#include "CSWColorComboBox.h"
// CSWColorComboBox
IMPLEMENT_DYNAMIC(CSWColorComboBox, CComboBox)
CSWColorComboBox::TColorProperty CSWColorComboBox::s_clrPropertys[MAX_COLOR_COUNT] =
{
TColorProperty(RGB(0x00, 0x00, 0x00), "黑色(Black)"),
TColorProperty(RGB(0x80, 0x00, 0x00), "褐红色(Maroon)"),
TColorProperty(RGB(0x00, 0x80, 0x00), "调和绿(Green)"),
TColorProperty(RGB(0x80, 0x80, 0x00), "橄榄色(Olive)"),
TColorProperty(RGB(0x00, 0x00, 0x80), "藏青色(Navy)"),
TColorProperty(RGB(0x80, 0x00, 0x80), "紫色(Purple)"),
TColorProperty(RGB(0x00, 0x80, 0x80), "鸭翅绿(Teal)"),
TColorProperty(RGB(0x80, 0x80, 0x80), "灰色(Gray)"),
TColorProperty(RGB(0xC0, 0xC0, 0xC0), "银色(Silver)"),
TColorProperty(RGB(0xFF, 0x00, 0x00), "红色(Red)"),
TColorProperty(RGB(0x00, 0xFF, 0x00), "绿色(Lime)"),
TColorProperty(RGB(0xFF, 0xFF, 0x00), "黄色(Yellow)"),
TColorProperty(RGB(0x00, 0x00, 0xFF), "蓝色(Blue)"),
TColorProperty(RGB(0xFF, 0x00, 0xFF), "紫红色(Fushcia)"),
TColorProperty(RGB(0x00, 0xFF, 0xFF), "青色(Aqua)"),
TColorProperty(RGB(0xFF, 0xFF, 0xFF), "白色(White)"),
};
CSWColorComboBox::CSWColorComboBox()
{
}
CSWColorComboBox::~CSWColorComboBox()
{
}
BEGIN_MESSAGE_MAP(CSWColorComboBox, CComboBox)
ON_WM_CREATE()
END_MESSAGE_MAP()
void CSWColorComboBox::CommonConstruct(void)
{
for (int nIndex = 0; nIndex < MAX_COLOR_COUNT; nIndex++)
{
int nItem = AddString(s_clrPropertys[nIndex].m_szName);
if (nItem == CB_ERRSPACE)
break;
else
SetItemData(nItem, s_clrPropertys[nItem].m_clrColor);
}
}
void CSWColorComboBox::DrawItem(LPDRAWITEMSTRUCT pDIStruct)
{
CDC dc;
if (!dc.Attach(pDIStruct->hDC))
return;
CString strName;
CRect rItemRect(pDIStruct->rcItem);
CRect rcFrame(rItemRect);
CRect rcText(rcFrame);
// 颜色边框画刷
CBrush brFrameBrush;
brFrameBrush.CreateStockObject(BLACK_BRUSH);
int nFrameWidth = 0;
int nItem = pDIStruct->itemID;
int nAction = pDIStruct->itemAction;
int nState = pDIStruct->itemState;
COLORREF clrColor = 0;
COLORREF clrNormal = GetSysColor(COLOR_WINDOW);
COLORREF clrSelected = GetSysColor(COLOR_HIGHLIGHT);
COLORREF clrText = GetSysColor(COLOR_WINDOWTEXT);
// 颜色框宽度
nFrameWidth = 40;
if (nState & ODS_SELECTED)
{
dc.SetTextColor((0x00FFFFFF & ~(clrText)));
dc.SetBkColor(clrSelected);
dc.FillSolidRect(&rcFrame, clrSelected);
}
else
{
dc.SetTextColor(clrText);
dc.SetBkColor(clrNormal);
dc.FillSolidRect(&rcFrame, clrNormal);
}
if (nState & ODS_FOCUS)
dc.DrawFocusRect(&rItemRect);
rcFrame.left += 2;
rcFrame.right = nFrameWidth;
rcFrame.top += 2;
rcText.left += (nFrameWidth + 2);
rcText.DeflateRect(CSize(2, 2));
if (nItem != -1)
{
GetLBText(nItem, strName);
if (nState & ODS_DISABLED)
{
clrColor = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
dc.SetTextColor(clrColor);
}
else
{
clrColor = GetItemData(nItem);
}
dc.SetBkMode(TRANSPARENT);
dc.TextOut(rcText.left, rcText.top, strName);
if (clrColor != RGB(0,0,1))
{
dc.FillSolidRect(&rcFrame, clrColor);
dc.FrameRect(&rcFrame, &brFrameBrush);
}
}
dc.Detach();
}
COLORREF CSWColorComboBox::GetSelColor()
{
int nSelIndex = GetCurSel();
if (nSelIndex == CB_ERR)
return RGB(0, 0, 0);
return GetItemData(nSelIndex);
}
void CSWColorComboBox::SelectColor(COLORREF color)
{
int nCount = GetCount();
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
if (color == GetItemData(nIndex))
SetCurSel(nIndex);
}
}
void CSWColorComboBox::SelectColor(LPCTSTR lpszName)
{
int nCount = GetCount();
CString sColorName;
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
GetLBText(nIndex, sColorName);
if (!sColorName.CompareNoCase(lpszName))
SetCurSel(nIndex);
}
}
void CSWColorComboBox::DeleteColor(LPCTSTR lpszName)
{
int nCount = GetCount();
CString strColorName;
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
GetLBText(nIndex, strColorName);
if (!strColorName.CompareNoCase(lpszName))
{
DeleteString(nIndex);
break;
}
}
}
void CSWColorComboBox::DeleteColor(COLORREF color)
{
int nCount = GetCount();
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
if (color == GetItemData(nIndex))
{
DeleteString(nIndex);
break;
}
}
}
int CSWColorComboBox::AddColor(LPCTSTR lpszName, COLORREF color)
{
int nIndex = InsertString(-1, lpszName);
if (nIndex != CB_ERR)
SetItemData(nIndex, color);
return nIndex;
}
void CSWColorComboBox::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
CComboBox::PreSubclassWindow();
CommonConstruct();
SetCurSel(0);
}