为Listbox 和 Combobox“添光加彩” Delphi中Listbox 和 Combobox是设置多项选择和单项选择最好的组件，但长久以来它们基本上只显示文字，看起来是否有点太单调，其实通过它们的Style属性，你的列表框和组合框也会是图文并茂的。这里有两个方法可帮你达成心愿。 方法一 创建一个新Form，在其中添加Listbox 和 Combobox组件，把Combobox的Style属性设为csOwnerDrawVariable，ListBox 的Style属性设为lbOwnerDrawVariable。这是因为只有 OwnerDraw 的TListBox 或者 TComboBox 允许显示对象（比如图形）和字符串。
程序源代码如下：
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs,
StdCtrls, Grids, DBGrids, Db, DBTables;
type
TForm1=class(TForm)
ComboBox1:TComboBox;
ListBox1:TListBox;
procedure FormCreate(Sender:TObject);
procedure FormClose(Sender:TObject; var Action:TCloseAction);
procedure ComboBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
procedure ComboBox1MeasureItem(Control:TWinControl; Index:Integer; var Height: Integer);
procedure ListBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
procedure ListBox1MeasureItem(Control:TWinControl; Index:Integer; var Height:Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var Form1:TForm1; MyBitmap1, MyBitmap2, MyBitmap3, MyBitmap4: TBitmap;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
MyBitmap1:=TBitmap.Create;
MyBitmap1.LoadFromFile('C:\Delphi\ding.bmp');
//指定图片文件是C:\Delphi\ding.bmp
MyBitmap2:=TBitmap.Create;
MyBitmap2.LoadFromFile('C:\Delphi\arrow1l.bmp');
MyBitmap3:=TBitmap.Create;
MyBitmap3.LoadFromFile('C:\Delphi\arrow1dl.bmp');
MyBitmap4:=TBitmap.Create;
MyBitmap4.LoadFromFile('C:\Delphi\arrow1dr.bmp');
ComboBox1.Items.AddObject('Bitmap1', MyBitmap1);
ComboBox1.Items.AddObject('Bitmap2', MyBitmap2);
ComboBox1.Items.AddObject('Bitmap3', MyBitmap3);
ComboBox1.Items.AddObject('Bitmap4', MyBitmap4);
ListBox1.Items.AddObject('Bitmap1', MyBitmap1);
ListBox1.Items.AddObject('Bitmap2', MyBitmap2);
ListBox1.Items.AddObject('Bitmap3', MyBitmap3);
ListBox1.Items.AddObject('Bitmap4', MyBitmap4);
end;
procedure TForm1.FormClose(Sender:TObject; var Action:TCloseAction);
begin
MyBitmap1.Free;
MyBitmap2.Free;
MyBitmap3.Free;
MyBitmap4.Free;
end;
procedure TForm1.ComboBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
var Bitmap:TBitmap; Offset:Integer;
begin
offset:=0;
with ComboBox1.Canvas do
begin
FillRect(Rect);
Bitmap:=TBitmap(ComboBox1.-Items.Objects[Index]);
if Bitmap <> nil then//粘贴图片
begin
//适当的空档使图片关系分明，clred为透明色
BrushCopy(Bounds(Rect.Left＋2, Rect.Top＋2, Bitmap.Width,
Bitmap.Height), Bitmap, Bounds(0, 0, Bitmap.Width,
Bitmap.Height), clred);
Offset:=Bitmap.width＋8;
//图片与文字的间隔以组件的Left属性计算
end;
TextOut(Rect.Left＋Offset, Rect.Top, Combobox1.Items[Index]);//显示文字
end;
end;
procedure TForm1.ListBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
var Bitmap:TBitmap; Offset:Integer;
begin
offset:=0;
with ListBox1.Canvas do
begin
FillRect(Rect);
Bitmap:=TBitmap(ListBox1.-Items.Objects[Index]);
if Bitmap <> nil then //粘贴图片
begin
BrushCopy(Bounds(Rect.Left＋2, Rect.Top＋2, Bitmap.Width,
Bitmap.Height), Bitmap, Bounds(0, 0, Bitmap.Width,
Bitmap.Height), clRed);
Offset:=Bitmap.width＋8;
//图片与文字的间隔以组件的Left属性计算
end;
TextOut(Rect.Left ＋ Offset, Rect.Top, Listbox1.Items[Index]);
//显示文字
end;
end;
end.
如果上下图片间隔不当，请调整组件的ItemHeight属性值。

方法二

以Listbox为例，将style属性设为lbOwnerDrawFixed，在OnDrawItem事件中写一段代码，也可以在列表框中的每一项前面加一小图标。
procedure TForm1.ListBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
var Bitmap:TBitmap; Offset:Integer;
begin
with (Control as TListBox).Canvas do
begin
FillRect(Rect);
Offset:=2;
Bitmap:=TBitmap.create;
Bitmap.LoadFromFile('d:\temp1\1.bmp');
//指定图文件是C:\Delphi\ding.bmp
BrushCopy(Bounds(Rect.Left＋2, Rect.Top,
Bitmap.Width, Bitmap.Height),
Bitmap, Bounds(0, 0, Bitmap.Width,
Bitmap.Height), clRed);
Offset:=Bitmap.width＋6;
TextOut(Rect.Left ＋ Offset, Rect.Top,
(Control as TListBox).Items[Index])
end;
end;
进一步，利用OnDrawItem事件的参数Index还可以在不同项前面添加不同的图标。还要告诉你的是，当用add方法为列表框或下拉框添加项目时，会自动执行OnDrawItem事件，这样新添加的项目前面也就有了一个图标。
(肖飞、王勇)