如何用TComboBox模拟TColorBox

今天在CSDN见到一位网友问及如何用TComboBox模拟TColorBox,一时兴起,写了一些代码。略加注释后发表到文档区,以备将来查询。
TColorBox是VCL中提供的选取颜色的组件,同TComboBox相同,两个组件都继承自TCustomComboBox,有很多相同的属性和方 法,如Style, ItemHeight,Canvas(这个属性是继承自TCustomCombo组件(TCustomCombo的父类)),TColorBox列出了系 统中定义的颜色字符串,每一项前面有个小方块,填充了该项目所代表的颜色,后面是颜色字符串,这种效果ComboBox中很容易实现。实现方法,就是 ccrun(老妖)所喜欢的自画。通过ComboBox的OnDrawItem方法实现画方块和绘制字符串。可是如何取得系统中定义的颜色字符串列表呢? 答案就是通过GetColorValues函数(类似的更有GetCharsetValues)。这个函数能够了取得系统中定义过的颜色字符串列表,原型 如下:
extern PACKAGE void __fastcall GetColorValues(Classes::TGetStrProc &Proc);

TGetStrProc的原型:
typedef void __fastcall (__closure *TGetStrProc)(const AnsiString S);

OK,下面开始写代码做测试。在Form上添加一个ComboBox,再添加一个ColorBox(作对比用)

因为我们的代码中需要动态的指定ComboBox的自画函数,所以在单元文档的.h中,TForm类中声明一下自画函数。当然,您能够通过在Design界面上选择ComboBox的OnDrawItem,然后双击,IDE会自动产生相应的声明和定义代码。

先来看看效果图:


自画函数的声明(.h文档):
publice: // User declarations
void __fastcall ComboBox1DrawItem(TWinControl *Control, int Index,
// 本文转自 C Builder 研究 - http://www.ccrun.com/article.asp?i=997&d=6rb201
TRect &Rect, TOwnerDrawState State);

自画函数的定义(.cpp文档):
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
TRect &Rect, TOwnerDrawState State)
{
TComboBox *cbb = (TComboBox *)Control;
String strText = cbb->Items->Strings[Index];
// 用白色填充当前项目所占的区域
cbb->Canvas->Brush->Color = clWhite;
cbb->Canvas->FillRect(Rect);
// 假如当前项目处于被选中状态
if(State.Contains(odSelected))
{
// 假如当前项拥有焦点,重画一次虚线框实现虚线框的擦除
if(State.Contains(odFocused))
::DrawFocusRect(cbb->Canvas->Handle, &Rect);
// 换一种颜色画边框,实现高亮效果
cbb->Canvas->Brush->Color = TColor(0x00FFB2B5);
cbb->Canvas->Rectangle(Rect.Left, Rect.Top,
Rect.Right, Rect.Bottom);
}
// by ccrun(老妖) 欢迎光临 C Builder研究 - http://www.ccrun.com
//
// 取得当前项字符串所代表的颜色

int nColor;
IdentToColor(strText, nColor);
cbb->Canvas->Brush->Color = TColor(nColor);
// 画边框和文字
cbb->Canvas->Rectangle(Rect.Left 2, Rect.Top 2, Rect.Left 18, Rect.Top 18);
cbb->Canvas->Font->Color = clBlack;
cbb->Canvas->Brush->Style = bsClear;
cbb->Canvas->TextOutA(Rect.Left 20, Rect.Top 4, strText);
}

以上是ComboBox组件自画项目的实现,我们还需要一些初始化工作,在TForm的构造函数中(当然也能够在Form的OnCreate事件中):
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ComboBox1->Items->Clear();
// 通过回调函数获取系统中定义的颜色名称
// 63 63 72 75 6E 2E 63 6F 6D
TGetStrProc AddValue = (TGetStrProc)&ComboBox1->Items->Add;
GetColorValues(TGetStrProc(AddValue));
// 改变ComboBox的风格使其能自画
ComboBox1->Style = csOwnerDrawFixed;
// ComboBox中每一项的高度
ComboBox1->ItemHeight = 20;
// 指定ComboBox的项目自画事件
ComboBox1->OnDrawItem = (TDrawItemEvent)&ComboBox1DrawItem;
// 使ComboBox选中第一个项目
ComboBox1->ItemIndex = 0;
}

你可能感兴趣的:(combobox)