線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3552
推到 Plurk!
推到 Facebook!

Delphi中ListBox控制項的六種特效

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-10-21 19:39:34 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料 Delphi中ListBox控制項的六種特效 ********************************************************************** Delphi5是Borland公司開發的全新的視覺化集成開發環境,它使用語法嚴密的Pascal語言,並封裝了Windows中的構件,形成了自己的一套控制項庫體系-VCL(Visual Component Library)。VCL控制項體系具有很強的擴展性,?開發者設計特殊視覺效果的控制項提供了技術支援。 本文就Delphi5中的TListBox控制項,通過多種手段實現了它的七種特殊視覺效果,以期對廣大程式愛好者在介面設計上有所?發與幫助。 一、 基礎知識 涉及TListBox自定義重繪的屬性和事件: 屬性: Style: 取值?lbStandard(標準風格),lbOwnerDrawFixed(所有者固定繪製風格),lbOwnerDrawVariable(所有者可變繪製風格) 說明: 1. 當Style = lbStandard時,使用控制項默認的繪製風格。 2. 當Style = lbOwnerDrawFixed時,用戶只能在控制項默認大小的區域繪圖。 3. 當Style = lbOwnerDrawVariable時,用戶可改變控制項默認的繪圖區域大小並決定如何繪圖。 事件: OnMeasureItem:當Style = lbOwnerDrawVariable時計算TListBox中某項的高度時調用。 OnDrawItem :當Style = lbOwnerDrawVariable時由用戶常式確定如何繪製TlistItem。 由此,可以看出,要實現定制介面風格的TListBox,首先,需要設置TlistBox的Style 屬性?lbOwnerDrawVariable,其次,需要寫自定義的重繪事件。 二、 特殊效果的實現 在表單(Form1)上放置5個ListBox,名稱分別?ListBox1……ListBox5,將所有ListBox的Style屬性設置?lbOwnerDrawVariable;在Form1上添加兩個TImageList控制項,命名?ImageList1,ImageList2;在ImageList1中裝入兩個16X16大小的圖示;添加兩個TButton控制項,命名?Button1,Button2;再添加一個TImage控制項,命名?Image1。其他操作,見下。 1. 具有圖示及熱鏈結效果的列表框 在ListBox1的Items屬性中添加幾個字串,並在ListBox1的OnDrawItem事件中編寫代碼如下: procedure TForm1.ListBox2DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var AIcon, BIcon: TIcon; begin try file://從上述ImageList1中裝入兩個圖示 AIcon := TIcon.Create; BIcon := TIcon.Create; file://裝入圖示到AIcon, BIcon ImageList1.GetIcon(0, AIcon); ImageList1.GetIcon(1, BIcon); file://填充繪圖區 ListBox1.Canvas.FillRect(Rect); file://判斷ListBox1中的當前重繪項是否被選中,根據狀態裝入不同的圖示 if odSelected in State then ListBox1.Canvas.Draw(Rect.Left, Rect.Top, AIcon) else ListBox1.Canvas.Draw(Rect.Left, Rect.Top, BIcon); file://輸出文字 ListBox1.Canvas.TextOut(Rect.Left AIcon.Width div 2, Rect.Top 2, ListBox1.Items[Index]); finally AIcon.Free; BIcon.Free; end; end; 注:也可在OnMeasureItem事件中改變列表項的高度。 2. 具有橫向捲軸效果的列表框 在Form1上Button1的Click事件中書寫如下代碼: procedure TForm1.Button1Click(Sender: TObject); begin SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, ListBox1.Width 30, 0); end; 具體橫向滾動區域的寬度可通過具體計算得出,在此從略。 3. 具有圖示,背景圖片及透明文字效果的列表框 說明: 1. 要使TListBox具有指定點陣圖的背景,須考慮到以下問題: 如果TListBox的Items足夠多,那?,在TListBox的OnDrawItem事件的Rect區域輸出點陣圖即可使整個TListBox的Canvas充滿點陣圖背景;反之,則會出現TListBox中上半部分有Item的地方有背景,下半部分沒有Item的部分仍然?白色,影響視覺效果。 2. TListBox的Color屬性決定了文本輸出時的背景,通常?clWindow,這樣用TextOut時就會出現不協調的白色文字背景。因此,要實現透明文字輸出效果,可以通過設置ListBox.Canvas.Brush.Style := bsClear,這樣,繪製的文字沒有背景色,從而實現文字透明輸出效果。 操作: 在ListBox2的Items屬性中添加幾個字串;設置Form1上的Image1的Picture屬性?一指定圖片。在ListBox2的OnDrawItem事件中書寫如下代碼: procedure TForm1.ListBox2DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var AIcon: TIcon; I, K : Integer; ARect, BRect: TRect; H : Integer; AStyle: TBrushStyle; begin try file://計算Item數量 I := ListBox2.Items.Count-1; AIcon := TIcon.Create; file://裝入圖示 ImageList1.GetIcon(0, AIcon); file://填充區域 ListBox2.Canvas.FillRect(Rect); file://計算Rect繪圖區的高度 H := Rect.Bottom - Rect.Top; file://如果當前項是Item的最後一項,則在Canvas上沒有Item的空白區繪製背景 if Index = I then begin K := 1; ARect := Rect; file://如果當前繪圖項的底部小於ListBox2的Canvas的底部,有空白區域 While ARect.Bottom < ListBox2.Canvas.ClipRect.Bottom do begin file://一次計算下一個繪圖區域 ARect.Top := Rect.Top K * H; ARect.Bottom := ARect.Top H; ListBox2.Canvas.stretchDraw(ARect, Image1.Picture.Bitmap); Inc(K); end; end; file://繪製當前項 ListBox2.Canvas.stretchDraw(Rect, Image1.Picture.Bitmap); file://繪製圖示 ListBox2.Canvas.Draw(Rect.Left, Rect.Top, AIcon); ARect := Rect; ARect.Left := Rect.Left AIcon.Width div 2; ARect.Top := ARect.top 2; file://保存當前畫筆的風格 AStyle := Listbox2.Canvas.Brush.Style; file://當前選中的Item要填充藍色背景 if odSelected in State then begin ListBox2.Canvas.Brush.Style := bsSolid; Listbox2.Canvas.Brush.Color := clBlue; end else begin file://未選中項透明背景,前景色?黑色 ListBox2.Canvas.Brush.Style := bsClear; Listbox2.Font.Color := clBlack; end; file://輸出文字 ListBox2.Canvas.TextOut(ARect.Left, ARect.top, ListBox2.Items[Index]); file://恢復當前畫筆的風格 ListBox2.Canvas.Brush.Style := AStyle; finally AIcon.Free; end; end; 以上方法實現了TListBox即具有背景圖片,又具有圖示和透明文字效果,極大的改善了TListBox的顯示效果。 4. 具有圖示,背景圖片,透明文字及文字對齊方式效果的列表框 要實現文字對齊效果,可通過Windows Api函數:DrawText實現。 操作: 將ListBox2的OnDrawItem事件中的代碼複製到ListBox3的OnDrawItem事件中,並將複製代碼中所有的ListBox2改?ListBox3。 將上述修改後代碼中的ListBox3.Canvas.TextOut(Rect.Left AIcon.Width div 2, Rect.Top 2, ListBox3.Items[Index]); 語句刪除,並在該處添加以下語句: file://計算除掉圖示所占區域後的區域,用於確定繪製文字的區域範圍 ARect := Rect; ARect.Left := Rect.Left AIcon.Width div 2; ARect.Top := ARect.top 2; file://Windows Api函數調用 DrawText(ListBox3.Canvas.Handle, PChar(ListBox3.Items[Index]), Length(ListBox3.Items[Index]), ARect, 0); file://0-左對齊, 1---居中, 2--右對齊 注:通知ListBox3重繪可通過命令ListBox3.Refresh實現 5. 照片列表框效果 在ListBox4的Items屬性中添加幾個字串;設置ImageList2的Width?148,Height?58;在ImageList2中裝入與ListBox4中Items相同字串數量的圖片,大小148 X 58圖元單位。 在ListBox4的OnMeasureItem事件中書寫如下代碼: procedure TForm1.ListBox4MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer); begin file://控制圖片的高度 Height := 59; end; 在ListBox4的OnDrawItem事件中書寫如下代碼: procedure TForm1.ListBox4DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var ABmp: TBitmap; begin try ABmp := TBitmap.Create; ImageList2.GetBitmap(Index, ABmp); ListBox4.Canvas.FillRect(Rect); ListBox4.Canvas.Draw(Rect.Left, Rect.Top, ABmp); finally ABmp.Free; end; end; 這種利用TListBox實現的照片框效果,對於照片,商品圖片的顯示有一定價值。 6. 以縮略圖方式瀏覽某個文件夾下圖片效果的列表框 在ListBox5的OnMeasureItem事件中書寫如下代碼: procedure TForm1.ListBox5MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer); begin file://控制圖片的高度 Height := 59; end; 在ListBox5的OnDrawItem事件中書寫如下代碼: procedure TForm1.ListBox5DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var file://圖片檔案名 Fn: string; ABmp: TBitmap; begin try ABmp := TBitmap.Create; Fn := ListBox5.Items[Index]; ABmp.LoadFromFile(ListBox5.Items[Index]); Dec(Rect.Bottom); ListBox5.Canvas.FillRect(Rect); ListBox5.Canvas.StretchDraw(Rect, ABmp); finally ABmp.Free; end; end; 設置Button2的Caption?"預覽",在其Click事件中書寫如下代碼: var sr: TSearchRec; Dir: string; begin Dir := ''; file://選擇目錄對話方塊,需要在Uses中加入對FileCtrl單元的引用聲明 if SelectDirectory('選擇圖片目錄', '', Dir) then begin ListBox5.Items.Clear; file://搜索該目錄下的所有bmp文件 if FindFirst(Dir '\*.bmp', faReadOnly, sr) = 0 then begin ListBox5.Items.Add(Dir '\' Sr.Name); while FindNext(sr) = 0 do begin ListBox5.Items.Add(Dir '\' Sr.Name); end; FindClose(sr); end; end; end; 以上六種方法將TBitmap, TIcon, TImage, TImageList結合使用,以及通過Windows API函數極大的改善了TListBox的外觀,也?定制修改TlistView, TtreeView等控制項的外觀提供了參考手段。上述方法在Delphi5下調試通過。
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-05-05 0:15:02
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!