後一頁
前一頁
回目錄
回首頁
第三章 字元串清單及應用(二)

3.1.4 往字元串清單中加入物件 

  字元串清單除了能在Strings屬性中貯存字元串外,還可以在Objects屬性中貯存物件。與Stings一樣,Objects也是可以索引的,它是物件的索引。

  在應用程式使用清單中的字元串與清單中是否有物件沒有多大關係。除非程式特地存取物件,否則Objects中的內容不變,Delphi只是存檔了這些資訊,應用程式在必要時對其進行操作。

  有些字元串清單忽略加入的物件。如TMemo部件中代表行的清單對加入其中的物件不存檔。還有一些字元串清單,把物件與字元串聯繫起來,如TNotebook部件的Pages屬性,它同時存檔著頁的名字和代表頁的物件。如果應用程式往Pages中加入或解除字元串,Delphi自動的加入或解除與之相應的物件。

  雖然程式可分配任何型式的物件到清單中,但最常用的是在自畫式控制中把點陣圖與字元串聯繫起來,注意點陣圖與字元串成對使用。

  Delphi在釋放物件的記憶體空間時並不破壞與之相應的字元串。 

3.1.4.1 操作字元串清單中的物件 

  對於字元串的每一種操作方法,清單中的物件均有相應的方法。例如,應用程式可利用物件的索引來存取物件。與字元串不同的是,不能省略Objects,因為Strings才是清單的缺省屬性。

  表3.1中總結了字元串對字元串和物件操作的方法。 

3.1 TStrings的字元串屬性和物件操作屬性的方法

────────────────────────────── 

                操    字 符 串        對   象

———————————————————————————————

   訪  問      Strings屬性                    Objects屬性

   加入項目      Add 方法       AddObjects方法

   插入項目      Insert方法      InsertObjects方法

           項目定位      Indexof方法                  IndexofObject方法

─────────────────────────────── 

  Delete,Clear,More操作整個項目,即解除字元串時把相應的物件也解除了。但LoadFromFile,SaveToFile方法只對字元串進行操作。 

3.1.4.2 加入物件 

  如果把物件與已存在的字元串聯繫起來,Delphi將分配給該物件同樣的索引號。例如,一個叫Fruits的清單中有字元串('apple'),程式可將名為AppleBitmap的點陣圖與apple字元相聯繫。 

  With Fruits do Objects[Indexof('apple')]:=AppleBitmap; 

另一種方法是呼叫清單的AddObject方法,AddObject有兩個參數:字元串和物件,如下: 

  Fruits AddObject('Apple',AppleBitmap); 

3.2 字元串清單應用 

          Delphi應用程式經常要用到字元串清單,我們編寫的strlist. dpr是應用字元串清單的簡單程式。程式執行狀態如圖3.2所示。列示方塊列出了螢幕支援的各種字形標簽,並且以標簽所代表的字形顯示在清單中;Tabs的標籤不只以字元串來表示,而且附有點陣圖。這就是所謂的自畫式控制。下面介紹字元串清單在自畫式控制中的應用。

         列示方塊、群群組合框、Tabset部件中有一個叫“自畫(Ownerdraw)”的風格,它能替代Windows的文本輸出,部件的自畫式控制在執行狀態對每個項目進行重新繪制。最常用的是用圖像代替文本輸出。

  自畫式控制有一個共同特點:它們都包含有項目清單,缺省情況下這些清單就是字元串清單,Windows把它們當成文本顯示。Delphi可以把字元串清單與某一物件相聯繫,這就使得應用程式能用物件來繪制項目。

  通常,建立自畫式控制有以下三個步驟:

  1. 設定自畫風格;

  2. 把圖像物件加入字元串清單中;

  3. 繪制自畫項目。 

3.2.1 設定自畫風格 

  每個能進行自畫式控制的部件都有一個叫Style的屬性,Style決定部件是以缺省方式還是以自畫方式繪制項目。

  對於列示方塊和群群組合框,也有自畫式風格選項,表3.2列出了Style的取值及含義。 

3.2 Style的取值及含義

────────────────────────────────

 

 Style              含  義         舉   例

—————————————————————————————————

 

 Fixed          每個項目有相同的高度      1bOwnerDrawFixed

 

        高度由ItenHeight屬性決定   csOwnerDrawFixed

Varible          每個項目有不同的高度     1bOwnweDrawVarible

 

        由執行數據決定                      csOwnerDrawVarible

───────────────────────────────── 

  tab-set與字元串網格的Style屬性通常是Varible.

Strlist程式中,列示方塊與tab-set取值如表3.3: 

3.3 列示方塊與tab-set的取值

──────────────────────────

    標簽         style

——————————————————————————

ListBox1                              lbOwnerDrawVariable

Tabset1                                tsOwnerDrawVariable

───────────────────────────

3.2.2 把圖像加入字元串清單 

  上節已介紹如何把物件加入字元串清單,例程把點陣圖物件加入Tabset1Tabs中: 

procedure TForm1.FormCreate(Sender: TObject);

var

Bitmap: TBitMap;

begin

Listbox1.Items := Screen.Fonts;

Bitmap := TBitmap.Create;

Bitmap.LoadFromFile('PHONE.BMP');

Tabset1.Tabs.AddObject('phone',Bitmap);

Bitmap := TBitmap.Create;

Bitmap.LoadFromFile('PRINTER.BMP');

Tabset1.Tabs.AddObject('printer ',Bitmap);

end; 

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的事件,這個事件也隨部件標簽不同而不同,常見的有OnDrawItemOnDrawTabOnDrawCell

  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;



後一頁
前一頁
回目錄
回首頁