後一頁 前一頁 回目錄 回首頁 |
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 把圖像加入字元串清單 上節已介紹如何把物件加入字元串清單,例程把點陣圖物件加入Tabset1的Tabs中: 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的事件,這個事件也隨部件標簽不同而不同,常見的有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; |
後一頁 前一頁 回目錄 回首頁 |