利用 lbOwnerDrawVariable 風格,覆寫 OnMeasureItem 與 OnDrawItem,將圖示 (ICO/BMP) 儲存於 Items.Objects,實現每行不同高度的圖文列表。並封裝為 TImageListBox 元件,提供 AddImage 方法簡化使用。
class TImageListBox : public TCustomListBox
{
private:
Graphics::TGraphic *tmpGraphic;
protected:
void __fastcall MyDrawItem(TWinControl *Control, int Index,
const TRect &Rect, TOwnerDrawState State);
void __fastcall MyMeasureItem(TWinControl *Control, int Index, int &Height);
public:
__fastcall TImageListBox(TComponent* Owner);
__fastcall ~TImageListBox();
void __fastcall AddImage(AnsiString Filename, AnsiString *Str);
};
void __fastcall TImageListBox::MyMeasureItem(TWinControl *Control, int Index, int &Height)
{
if (tmpGraphic) Height = tmpGraphic->Height + 2;
}
void __fastcall TImageListBox::MyDrawItem(TWinControl *Control, int Index,
const TRect &Rect, TOwnerDrawState State)
{
const int Offset = 2;
TCanvas *cv = ((TListBox*)Control)->Canvas;
cv->FillRect(Rect);
Graphics::TGraphic *img = (Graphics::TGraphic*)(Items->Objects[Index]);
cv->Draw(Rect.Left + Offset, Rect.Top, img);
if (img) Offset += img->Width + 4;
cv->TextOut(Rect.Left + Offset, Rect.Top,
((TListBox*)Control)->Items->Strings[Index]);
}
void __fastcall TImageListBox::AddImage(AnsiString Filename, AnsiString *Str)
{
if (Filename.Pos(".ico")) {
tmpGraphic = new Graphics::TIcon(); tmpGraphic->LoadFromFile(Filename);
Items->AddObject(*Str, (TObject*)tmpGraphic);
}
else if (Filename.Pos(".bmp")) {
tmpGraphic = new Graphics::TBitmap(); tmpGraphic->LoadFromFile(Filename);
Items->AddObject(*Str, (TObject*)tmpGraphic);
}
tmpGraphic = NULL;
}
__fastcall TImageListBox::TImageListBox(TComponent* Owner) : TCustomListBox(Owner)
{
Style = lbOwnerDrawVariable;
OnDrawItem = MyDrawItem;
OnMeasureItem = MyMeasureItem;
}
__fastcall TImageListBox::~TImageListBox()
{
for (int i = 0; i < Items->Count; i++)
if (Graphics::TGraphic *g = (Graphics::TGraphic*)Items->Objects[i])
delete g;
}
// 表單建構函數
TImageListBox *Til = new TImageListBox(this);
Til->Parent = this; Til->Width = 80; Til->Height = 90;
Til->AddImage("1.ico", "First");
Til->AddImage("2.bmp", "Second");
// 表單銷毀
delete Til;