Delphi中ListBox控制項的六種特效 |
|
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 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 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |