在看程式碼之前先給大家附上效果圖:
廢話不多說了,直接給大家貼程式碼了。
unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls, ImgList;typeTForm1 = class(TForm)btn1: TButton;lv1: TListmList1: TList; lv1CustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);procedure lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDraw); var DefaultustomListView; Item: TListItem; State: TCustomDState; var DefaultDd. trckbr1Change(Sender: TObject);privatefunction ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementationation {sCommCtrl}/RCommR. procedure DrawSubItem(LV: TListView; Item: TListItem; SubItem: Integer; Prosition: Single; Max, Style: Integer; IsShowProgress: Boolean; DrawColor: TColor = $00005B00; FrameColor: TColor = $00002F00);//取得SubItemRfunction Gets); iItem, iSubItem: Integer): TRect;varRect: TRect;beginListView_GetSubItemRect(hWndLV, iItem, iSubItem, iSubItem, @Rect);Result := Rect;end;varPaintRect, R: TRect;i, iWidth, x, y: Integergin; := GetItemRect(lv.Handle, Item.Index, SubItem);R := PaintRect;if Prosition >= Max thenProsition := 100elsebeginif Prosition <= 0 thenProsition := 0elseProsition := Round((Prosition / MAX) * 100); and (not IsShowProgress) thenCanvas.FillRect(r) //如果是0 ,直接顯示空白elsebegin//先填入背景Canvas.FillRect(r);Canvas.Brush.Color := Color;//畫一個外框InflateRect(R, -2, -2);Canvas. Brush.Color := FrameColor;Canvas.FrameRect(R);Canvas.Brush.Color := Color;InflateRect(R, -1, -1);//InflateRect(R,-1,-1);//根據百分比計算要花的進度條內容概述iWidth := R.Right - Round((R.Right - R.Left) * ( (100 - Prosition) / 100));case Style of0: //實心beginCanvas.Brush.Color := DrawColor;R.Right := iWidth;Canvas.FillRect(R);end;1: //垂直線填充begini := r.Left;while i < iWidth dobeginCanvas.Pen.Color := Color;Canvas.MoveTo(i, R.Top);Canvas .Pen.Color := DrawColor;Canvas.LineTo(i, R.Bottom);Inc(i, 3);end;end;end; //case end//畫好進度條後,現在要做的就是顯示進度數字了Canvas.Brush.Style := bsClear;if Prosition = Round(Prosition) thenS := Format ('%d%%', [Round(Prosition)])elseS := FormatFloat('#0.0', Prosition);with PaintRect dobeginx := Left + (Right - Left + 1 - Canvas.TextWidth(S)) div 2;y := Top + (Bottom - Top + 1 - Canvas.TextHeight(S)) div 2;end;SetBkMode(Canvas. Handle, TRANSPARENT);Canvas.TextRect(PaintRect, x, y, S);end;//畫完恢復Canvas.Brush.Color := Color;end;end;procedure TForm1.lv1CustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);beginend;//上面是畫進度條的,現在要給TlistView處理Item重繪的訊息,事件是OnCustomDrawItem,需要說明的是,如果想要隨心所欲的自畫Item,那麼就要全部自己來完成,不再需要係統來處理:procedure TForm1.lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);varBoundRect, Rect: TRect;i: integer;TextFormat: Word;LV: TListView; //這個子程序是用來畫CheckBox和ImageList的procedure Draw_CheckBox_ImageList(r: TRect; aCanvas: TCanvas; Checked: Booleanvas; );varR1: TRect;i: Integer;beginif Sender.Checkboxes thenbeginaCanvas.Pen.Color := clBlack;aCanvas.Pen.Width := 2;//畫CheckBox外框aCanvas.Rectangle(R.Left + 2, R.Top + 2, R.Left + 14, R.Bottom - 2);if Checked then //畫CheckBox的鉤beginaCanvas.MoveTo(R.Left + 4, R.Top + 6);aCanvas.LineTo(R.Left + 6, R.Top + 11);aCanvas.LineTo(R.Left + 11, R.Top + 5);end;aCanvas.Pen.Width := 1;end;//開始畫圖示i := 2; //ImageIndex的值,可以任意if i > -1 thenbegin//取得圖示的RECTif Boolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) thenbegin//ImageList_Stats.Draw(LV.Canvas, R1.Left, R1.Top, i); item.ImageIndex > -1 thenLV.SmallImages.Draw(LV.Canvas, R1.Right + 2, R1.Top, item.ImageIndex);end;end;end;beginLV := TListView(Sender);BoundRect := Item.DisplayRect(drBounds);InflateRect (BoundRect, -1, 0);//這個地方你可以依照自己的要求設定成想要的顏色,實作突顯LV.Canvas.Font.Color := clBtnText;//檢視是否被選取if Item.Selected thenbeginif cdsFocused in State thenbeginLV. Canvas.Brush.Color := $00ECCCB9; // //clHighlight;endelsebeginLV.Canvas.Brush.Color := $00F8ECE5; //clSilver;end;endelsebeginif (Item.Index mod 2) = 0 thenLV.Canvas.Brush.Color := clWhiteelseLV.Canvas.Brush.Color := $00F2F2F2;end;LV.vasvas.FillRect(BoundBect) ; // 初始化背景for i := 0 to LV.Columns.Count - 1 dobegin//取得SubItem的RectListView_GetSubItemRect(LV.Handle, Item.Index, i, LVIR_LABEL, @Rect);case LV.Columns[i].Alignment oftaLeftJustify:TextFormat := DTFTP:Right TextFormat := DT_CENTER;elseTextFormat := DT_CENTER;end;case i of0: //畫Caption,0表示Caption,不是Subitembegin//先畫選擇框與圖示Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked);//再畫Caption的文字InflateRect(Rect, -(5 + il1.Width), 0); //向後移3個像素,避免被後面畫線框時覆蓋//InflateRect(Rect, -(5), 0); //向後移3個像素,避免被後面畫線框時覆蓋DrawText( LV.Canvas.Handle, PAnsiChar(Item.Caption), Length(Item.Caption), Rect, DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat);end;1..MaxInt: //畫SubItem[i]beginif (i - 1) = 1 then //顯示狀態條,本範例是第三欄顯示,可以隨便定beginDrawSubItem(LV, Item, i , StrToFloatDef(Item.SubItems[i - 1], 0), 100, 0, True);endelsebegin//畫SubItem的文字InflateRect(Rect, -2, -2);if i - 1 <= Item.SubItems.Count - 1 thenDrawText(LV.Canvas.Handle, PCHAR(Item.SubItems[i - 1]), Length(Item.SubItems[i - 1]), Rect, DT_VCENTER or DT_SINGLELINE或 DT_END_ELLIPSIS or TextFormat);end;end;end; //end caseend; //end forLV.Canvas.Brush.Color := clWhite;if Item.Selected then //畫出條外框beginif cdsFocused in State then//控制項是否處於啟動狀態LV.Canvas.Brush.Color := $00DAA07A // $00E2B598; //clHighlight;elseLV.Canvas.Brush.Color := $00E2B598; //$00DAA07A // clHighlight;LV.Canvas.FrameRect(BoundRect); //end;DefaultDraw := False; //不讓系統畫了with Sender.Canvas doif Assigned(Font.OnChange) thenFont.OnChange(Font);end;function TForm1.ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;beginResult := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex); : TListItem;begin//使用:item := LV1.Items[1];if Item = nil thenExit;item.subitems[1] := '30'; //設定為30%//然後刷新這個itemReDrawItem(LV1. handle, Item.Index);end;procedure TForm1.trckbr1Change(Sender: TObject);varItem: TListItem;begin//使用:item := LV1.Items[0];item.subitems[1] := IntToStr(trckbr1.Position);//然後刷新這個itemReDrawItem(LV1.handle, Item.Index);end; end. object Form1: TForm1Left = 416Top = 301Width = 494Height = 170Caption = 'Form1'Color = clBtnFaceFont.Charset = DEFAULT_CHARSETFont.Color = clWindowTextFont.Height = -11Font.Name = 'MS Sans Serif'Font.Style = []OldCreateOrder = FalsePixelselsIns Serif'Font.Style = []OldCreateOrder = FalsePixelselsIns Serif'Font.Style = []OldCreateOrder = FalsePixelselsInjmin = 196355p 96Width = 75Height = 25Caption = 'btn1'TabOrder = 0OnClick = btn1Clickendobject lv1: TListViewLeft = 16Top = 8Width = 457Height = 81Columns = <itememtion = 1'Width = 457Height = 81Columns = <itememtion = 'Capsidendemtion = Capidend 100enditemCaption = '進度'Width = 100enditemCaption = '資源'Width = 100end>GridLines = TrueItems.Data = {5B0000000200000002000000000000000FFFFFF02000000000000006B4F3B8BBCECC04D3CECFB70333354D01000000F FFFFFFFFFFFFFFF020000000000000008446F7461B4ABC6E604D3CECFB7043130304DFFFFFFFFFFFFFFFF}ShowWorkAreas = TrueSmallImages = il1TabOrder = 1ViewStyle = vsReportOnCustomDrawItem = lv1CustomDrawItemendobject trckbr1: TTrackBarLeft = 16Top = 96Width = 233Height = 33MaxLeft = 16Top = 96Width = 233Height = 33MaxLeft = 16Top = 96Width = 233Height = 33MaxLeft = 10Tophanild TImageListLeft = 384Top = 96Bitmap = {