قبل النظر إلى الكود، سأرفق لك عرضًا:
بدون مزيد من اللغط، سأقوم بنشر الكود لك.
Unit Unit1;واجهاتاستخداماتWindows، الرسائل، SysUtils، Variants، Classes، Graphics، Controls، Forms،Dialogs، StdCtrls، ComCtrls، ImgList؛typeTForm1 = class(TForm)btn1: TButton;lv1: TListView;trckbr1: TTrackBar;il1: TImageList;procedure lv1CustomDraw (المرسل: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean); الإجراء lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); TObject);وظيفة خاصة ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;{ الإعلانات الخاصة }public{ الإعلانات العامة }end;varForm1: TForm1;implementationusesCommCtrl;{$R *.dfm}// إجراء رسم شريط الحالة DrawSubItem(LV) : TListView العنصر: TListItem؛ العرض: فردي؛ النمط: عدد صحيح؛ IsShowProgress: Boolean; DrawColor: TColor = $00005B00; TRect ;varRect: TRect;beginListView_GetSubItemRect(hWndLV, iItem, iSubItem, iSubItem, @Rect);Result := Rect;end;varPaintRect, R: TRect;i, iWidth, x, y: Integer;S: string;beginwith lv dobeginPaintRect := GetItemRect( lv.Handle، Item.Index، 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 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; end// بعد رسم شريط التقدم، كل ما عليك فعله الآن هو عرض رقم التقدم Canvas.Brush.Style := bsClear;if Prosition = Round(Prosition) ثمS := 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 يجب توضيح ذلك، إذا كنت تريد رسم العناصر الخاصة بك كما تريد، فيجب عليك القيام بذلك بنفسك ولم تعد بحاجة إلى النظام للتعامل معها: الإجراء 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.CheckboxesthenbeginaCanvas.Pen.Color := clBlack;aCanvas.Pen.Width := 2;// ارسم الإطار الخارجي لـ CheckBox aCanvas. مستطيل (R.يسار + 2، R.Top + 2، R.Left + 14، R.Bottom - 2)؛ إذا تم تحديده، // ارسم خطاف CheckBox beginCanvas.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 عشوائية إذا كنت > -1 ثم تبدأ // احصل على RECT للأيقونة if Boolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) ثم ابدأ //ImageList_Stats.Draw(LV.Canvas, R1.Left, R1.Top, i);if 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 ثمbeginif cdsFocused in State ثمbeginLV. 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: // ارسم تسمية توضيحية، 0 تعني تسمية توضيحية، وليس 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 ثم //عرض شريط الحالة، هذا المثال هو عرض العمود الثالث، يمكنك تخصيص beginDrawSubItem(LV, Item, i، 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 ثم //ارسم مخطط الشريط المحدد beginif cdsFocused في الحالة ثم/ /ما إذا كان عنصر التحكم نشطًا LV.Canvas.Brush.Color := $00DAA07A // $00E2B598; //clHighlight;elseLV.Canvas.Brush.Color := $00E2B598; //$00DAA07A // clHighlight;LV.Canvas.FrameRect(BoundRect); //end;DefaultDraw := False; مع تعيين Sender.Canvas (Font.OnChange) ثمFont.OnChange(Font);end;function TForm1.ReDrawItem(HwndLV: HWND; ItemIndex: عدد صحيح): boolean;beginResult := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex);end;إجراء TForm1.btn1Click(Sender: TObject);varItem: TListItem;begin//Use: item: = LV1.Items[1];if Item = nilthenExit;item.subitems[1] := '30'; //تعيين على 30%//ثم قم بتحديث هذا itemReDrawItem(LV1.handle, Item.Index);end;procedure TForm1.trckbr1Change(Sender: TObject);varItem: TListItem;begin//Use: item := LV1.Items[0];item.subitems[1] := IntToStr(trckbr1.Position);// ثم قم بتحديث هذا itemReDrawItem(LV1.handle, Item.Index);end;end.كائن Form1: TForm1Left = 416Top = 301Width = 494 الارتفاع = 170 تسمية توضيحية = 'Form1'اللون = clBtnFaceFont.Charset = DEFAULT_CHARSETFont.Color = clWindowTextFont.Height = -11Font.Name = 'MS Sans Serif'Font.Style = []OldCreateOrder = FalsePixelsPerInch = 96TextHeight = 13object btn1: TButtonLeft = 272Top = 96العرض = 75Height = 25Caption = 'btn1'TabOrder = 0OnClick = btn1Clickendobject lv1: TListViewLeft = 16Top = 8Width = 457Height = 81Columns = <itemCaption = 'Name'Width = 100enditemCaption = 'Category'Width = 100enditemCaption = 'Progress'Width = 100enditemCaption = 'Resource'Width = 100end>GridLines = TrueItems.Data = {5B000000020000000200000000000000FFFFFFFF02000000000000006B4F3B8BBCECC04D3CECFB70333354D01000000F FFFFFFFFFFFFFF020000000000000008446F7461B4ABC6E604D3CECFB7043130304DFFFFFFFFFFFFFFFF}إظهارمناطق العمل إيل1: TImageListLeft = 384Top = 96Bitmap = {