當控制項 Style = lbOwnerDrawFixed/Variable 等自繪模式時,Windows 不再繪製項目,改由應用程式處理 OnMeasureItem(測量尺寸)與 OnDrawItem(實際繪製)事件。關鍵在於 TStrings.Objects 陣列可攜帶任意物件(常見為 TBitmap),實現圖文並茂。
決定各項目顯示區域大小。ListBox/ComboBox 僅可設高度(寬度固定為控制項寬度),TabSet 則設寬度。參數包含 Index 及 var Height/Width。範例:依字體名稱設定行高:
procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
begin
with ListBox1.Canvas do
begin
Font.Name := ListBox1.Items[Index];
Height := TextHeight('A');
end;
end;
在 OnDrawItem 中實際繪製。參數:Control、Index、Rect(繪製矩形)、State(選中/焦點等狀態)。範例:以項目對應字體繪製字體名稱:
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
with ListBox1.Canvas do
begin
FillRect(Rect);
Font.Name := ListBox1.Items[Index];
TextOut(Rect.Left, Rect.Top, ListBox1.Items[Index]);
end;
end;
OnMeasureTab 計算寬度(文字+位圖),OnDrawTab 同時輸出位圖與文字:
procedure TForm1.TabSet1DrawTab(Sender: TObject; TabCanvas: TCanvas; R: TRect; Index: Integer; Selected: Boolean);
var Bitmap: TBitmap;
begin
Bitmap := TBitmap(TabSet1.Tabs.Objects[Index]);
with TabCanvas do
begin
Draw(R.Left, R.Top + 4, Bitmap);
TextOut(R.Left + 2 + Bitmap.Width, R.Top + 2, TabSet1.Tabs[Index]);
end;
end;