VC++ CComboBox自绘(颜色下拉列表框)

VC++(基础篇) 同时被 3 个专栏收录
61 篇文章 0 订阅
58 篇文章 0 订阅

使用前,请将控件的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);
}

 

  • 1
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值