ก่อนที่จะดูโค้ด ฉันจะแนบการเรนเดอร์ให้กับคุณ:
เพื่อเป็นการไม่ให้เสียเวลา ฉันจะโพสต์โค้ดให้คุณ
หน่วย Unit1;อินเทอร์เฟซ Windows, ข้อความ, SysUtils, ตัวแปร, คลาส, กราฟิก, การควบคุม, แบบฟอร์ม, กล่องโต้ตอบ, StdCtrls, ComCtrls, ImgList; typeTForm1 = class (TForm) btn1: TButton; lv1: TListView; trckbr1: TTrackBar; il1: TImageList; ขั้นตอน lv1CustomDraw(ผู้ส่ง: TCustomListView; const ARect: TRect; var DefaultDraw: บูลีน); ขั้นตอน lv1CustomDrawItem; รายการ: TListItem; var DefaultDraw: บูลีน); TObject);privatefunction ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementationusesCommCtrl;{$R *.dfm}//ขั้นตอนแถบสถานะการวาด DrawSubItem(LV : TListView; รายการ: TListItem; Prosition: Single; Max, Style: Integer; IsShowProgress: Boolean; DrawColor: TColor = $00005B00; FrameColor: TColor = $00002F00);// รับฟังก์ชันพื้นที่ของ SubItem GetItemRect(hWndLV: HWnd; iItem, iSubItem: Integer): TRect ;varRect: TRect;beginListView_GetSubItemRect(hWndLV, iItem, iSubItem, iSubItem, @Rect);ผลลัพธ์ := Rect;end;varPaintRect, R: TRect;i, iWidth, x, y: Integer;S: string;beginwith lv dobeginPaintRect := GetItemRect( lv.Handle, รายการ.ดัชนี, SubItem);R := PaintRect;if Prosition >= Max แล้ว Prosition := 100elsebeginif Prosition <= 0 แล้ว Prosition := 0elseProsition := Round((Prosition / MAX) * 100);end;if (Prosition = 0) และ (ไม่ใช่ IsShowProgress ) แล้วCanvas.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 := สี;InflateRect(R, -1, -1);//InflateRect(R,-1,-1);//คำนวณภาพรวมเนื้อหาแถบความคืบหน้าตามเปอร์เซ็นต์ iWidth := R.Right - Round((R.Right - R.Left) * ( ( 100 - Prosition) / 100));รูปแบบตัวพิมพ์ของ0: //Solid beginningCanvas.Brush.Color := DrawColor;R.Right := iWidth;Canvas.FillRect(R);end;1: //การเติมเส้นแนวตั้ง beginningi := r.Left;ในขณะที่ 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) แล้วก็S := Format('%d%%', [รอบ(ตำแหน่ง) )])elseS := FormatFloat('#0.0', Prosition);ด้วย PaintRect dobeginx := ซ้าย + (ขวา - ซ้าย + 1 - Canvas.TextWidth(S)) div 2;y := 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;ขั้นตอน TForm1.lv1CustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);beginend;//ด้านบนคือการวาดแถบความคืบหน้า ตอนนี้เราจำเป็นต้องประมวลผลข้อความ Item redraw สำหรับ TlistView ต้องอธิบายว่าถ้าจะวาดไอเทมเองตามใจชอบก็ต้องทำเองทั้งหมดและไม่ต้องใช้ระบบมาจัดการอีกต่อไป: ขั้นตอน TForm1.lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);varBoundRect, Rect: TRect;i: integer;TextFormat: Word;LV: TListView; //กระบวนการย่อยนี้ใช้ในการวาด ขั้นตอนของ CheckBox และ ImageList Draw_CheckBox_ImageList(r: TRect; aCanvas: TCanvas; Checked: Boolean);varR1: TRect;i: Integer;beginif Sender.Checkboxes แล้วก็beginaCanvas.Pen.Color := clBlack;aCanvas.Pen.Width := 2;//วาดกล่องกาเครื่องหมายด้านนอก aCanvas. สี่เหลี่ยมผืนผ้า (ซ้าย + 2, R.บน + 2, R.ซ้าย + 14, R.Bottom - 2);ถ้าเลือกแล้ว //วาดตะขอของ CheckBox beginningCanvas.MoveTo(R.Left + 4, R.Top + 6);aCanvas.LineTo(R.Left + 6, R.Top + 11) ; aCanvas.LineTo(R.ซ้าย + 11, R.Top + 5);end;aCanvas.Pen.Width := 1;end;//เริ่มวาดไอคอน i := 2; //ค่าของ ImageIndex สามารถกำหนดเองได้หาก i > -1 จากนั้นเริ่มต้น//รับ RECT ของไอคอนหาก Boolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) จากนั้นเริ่มต้น//ImageList_Stats.Draw(LV.Canvas, R1.Left, R1.Top, i);ถ้า item.ImageIndex > -1 แล้วLV.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;//ตรวจสอบว่าได้เลือกไว้หรือไม่หาก Item.Selected แล้วเริ่มต้นถ้า cdsFocused ใน State แล้วเริ่มLV Canvas.Brush.Color := $00ECCCB9; // //clHighlight;endelsebeginLV.Canvas.Brush.Color := $00F8ECE5; //clSilver;end;endelsebeginif (Item.Index mod 2) = 0 แล้วLV.Canvas.Brush.Color := clWhiteelseLV.Canvas.Brush.Color := $00F2F2F2;end;LV.Canvas.FillRect(BoundRect) ; // เริ่มต้นพื้นหลังสำหรับ i := 0 ถึง LV.Columns.Count - 1 dobegin//รับ RectListView_GetSubItemRect(LV.Handle, Item.Index, i, LVIR_LABEL, @Rect);case LV.Columns[i].Alignment oftaLeftJustify:TextFormat := DT_LEFT;taRightJustify:TextFormat := DT_RIGHT;taCenter:TextFormat : = DT_CENTER;elseTextFormat := DT_CENTER;end;case i of0: //Draw Caption, 0 หมายถึง Caption ไม่ใช่ Subitembegin//วาดกล่องตัวเลือกและไอคอนก่อน Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked);//จากนั้นวาด คำบรรยาย TextInflateRect (Rect, - (5 + il1.Width), 0); // ย้ายกลับไป 3 พิกเซลเพื่อหลีกเลี่ยงการเขียนทับเมื่อวาดโครงร่างในภายหลัง // InflateRect (Rect, - (5), 0); // ย้าย 3 พิกเซลกลับไปเพื่อหลีกเลี่ยงการเขียนทับเมื่อวาดโครงร่างในภายหลัง DrawText ( LV. Canvas.Handle, PAnsiChar(Item.Caption), ความยาว(Item.Caption), Rect, DT_VCENTER หรือ DT_SINGLELINE หรือ DT_END_ELLIPSIS หรือ TextFormat);end;1..MaxInt: //Draw SubItem[i]beginif (i - 1) = 1 จากนั้น //แสดงแถบสถานะ ตัวอย่างนี้คือการแสดงคอลัมน์ที่สาม คุณสามารถปรับแต่ง beginningDrawSubItem(LV, Item, ฉัน , StrToFloatDef(Item.SubItems[i - 1], 0), 100, 0, True);endelsebegin//วาดข้อความของ SubItemInflateRect(Rect, -2, -2);if i - 1 <= Item.SubItems.Count - 1 แล้วDrawText(LV.Canvas.Handle, PCHAR(Item.SubItems[i - 1]), ความยาว(Item.SubItems[i - 1]), Rect, DT_VCENTER หรือ DT_SINGLELINE หรือ DT_END_ELLIPSIS หรือ TextFormat);end;end;end; //end caseend; //end forLV.Canvas.Brush.Color := clWhite;if Item.Selected แล้ว //วาดโครงร่างแถบที่เลือกไว้ beginningif cdsFocused in State แล้ว/ /ไม่ว่าการควบคุมจะทำงานอยู่หรือไม่ LV.Canvas.Brush.Color := $00DAA07A // $00E2B598; //clHighlight;elseLV.Canvas.Brush.Color := $00E2B598; //$00DAA07A // clHighlight;LV.Canvas.FrameRect(BoundRect); //end;DefaultDraw := False; ด้วย Sender.Canvas doif Assigned(Font.OnChange) แล้วก็Font.OnChange(Font);end;function TForm1.ReDrawItem(HwndLV: HWND; ItemIndex: จำนวนเต็ม): บูลีน;beginResult := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex);end;ขั้นตอน TForm1.btn1Click(ผู้ส่ง: TObject);varItem: TListItem;เริ่มต้น//ใช้: รายการ: = LV1.Items[1];if Item = nil thenExit;item.subitems[1] := '30'; //ตั้งค่าเป็น 30%//จากนั้นรีเฟรช itemReDrawItem(LV1.handle, Item.Index);end;procedure TForm1.trckbr1Change(ผู้ส่ง: TObject);varItem: TListItem;begin//ใช้: รายการ := LV1.Items[0];item.subitems[1] := IntToStr(trckbr1.Position);//จากนั้นรีเฟรช itemReDrawItem(LV1.handle, Item.Index);end;end วัตถุ Form1: TForm1Left = 416Top = 301Width = 494ความสูง = 170คำบรรยาย = 'Form1'Color = clBtnFaceFont.Charset = DEFAULT_CHARSETFont.Color = clWindowTextFont.Height = -11Font.Name = 'MS Sans Serif'Font.Style = []OldCreateOrder = FalsePixelsPerInch = 96TextHeight = 13object btn1: TButtonLeft = 272Top = 96Width = 75Height = 25Caption = 'btn1'TabOrder = 0OnClick = btn1Clickendobject lv1: TListViewLeft = 16Top = 8Width = 457Height = 81Columns = <itemCaption = 'ชื่อ'Width = 100enditemCaption = 'หมวดหมู่'Width = 100enditemCaption = 'ความคืบหน้า'ความกว้าง = 100enditemCaption = 'ทรัพยากร'ความกว้าง = 100end>GridLines = TrueItems.Data = {5B000000020000000200000000000000FFFFFFFF02000000000000006B4F3B8BBCECC04D3CECFB70333354D01000000F FFFFFFFFFFFFFFF020000000000000008446F7461B4ABC6E604D3CECFB7043130304DFFFFFFFFFFFFFFFF}แสดงพื้นที่ทำงาน อิล1: TImageListLeft = 384ด้านบน = 96บิตแมป = {