3.2.3 繪制自畫項目
當部件的Style屬性是自畫式時,Windows不再繪制部件,相反Windows為每個可視項目產生事件,而應用程序必須在事件中繪制項目。
在應用程序繪制自畫控制之前,Windows產生測量項目事件,這個事件告訴程序項目顯示的位置 。
通常由Windows決定項目顯示的大小,但應用程序可以處理這個事件並自己選擇顯示區域。例如,程序要用位圖代替文本顯示,則需要把區域設置成位圖的大小。測量項目事件的名稱隨部件的名稱不同而不同,對於列表框和組合框,該事件叫OnMeasureItem。對於Tabset,該事件叫OnMeasureTab。
測量項目事件有兩個重要參數: 項目索引號與項目的大小。這個大小是變化的。後繼項目的輸出位置由前面項目的大小決定。例如,在自畫式列表框中,如果應用程序把第一個項目的高度設置成5個象素點,則第二個項目在第六個象素點開始輸出。列表框和組合框中,應用程序只能設置成項目的高度,而項目的寬度就是部件的高度。在Tabset中,tabs的寬度是可變的,而高度則是固定的。自畫式網格允許應用程序改變網格單元的高度和寬度。
OnMeasureItem的聲明如下:
ListBox1 MeasureItem(Control: TwinControl;Index: Integer; var Height: Integer);
例程中響應OnMeasureItem事件的代碼如下:
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;
procedure TForm1.TabSetMeasureTab(Sender: TObject; Index: Integer;
var TabWidth: Integer);
var
BitmapWidth: Integer;
begin
BitmapWidth := TBitmap( TabSet1.Tabs.Objects[Index]).Width;
Inc(TabWidth, 2 + BitmapWidth);
end;
在OnMeasureItem事件發生後,Windows激發一個叫OnDrawItem的事件,這個事件也隨部件名稱不同而不同,常見的有OnDrawItem、OnDrawTab、OnDrawCell。
OnMeasureItem的聲明如下:
DrawItem( Control: TWinControl; Index: integer; Rect: TRect; State: TOwnerDraw);
其中Control是包含項目的部件引用
Index 是項目的索引號
Rect 是繪制的矩形
State 是項目的狀態,如選中,得到焦點等。
在例程的列表框中,所列項目是屏幕支持的各種字體名稱,當列表框發生OnDrawItem事件時,程序把輸出字體設置成該項目所代表的字體,因而列表框的項目呈現出不同的字體,其代碼如下:
procedure TForm1.DrawItem(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;
在Tabset部件中,則把位圖與文本同時輸出,其代碼如下:
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;