TA的每日心情 | 开心 2024-12-9 18:45 |
---|
签到天数: 124 天 [LV.7]常住居民III
|
欢迎您注册加入!这里有您将更精采!
您需要 登录 才可以下载或查看,没有账号?注册
x
TListView的Item条一般是由系统自画的,但电驴就实现了自画,使之看起来很漂亮,我们用DELPHI也可以实现!
首先要引用CommCtrl单元,这是TListView底层控制单元:
- uses
- CommCtrl;
- //画状态条
- procedure DrawSubItem(LV: TListView; Item: TListItem; SubItem: Integer;
- Prosition: Single; Max, Style: Integer; IsShowProgress: Boolean;
- DrawColor: TColor = $00005B00;
- FrameColor: TColor = $00002F00);
- //获取SubItem的区域
- function GetItemRect(LV_Handle, iItem, iSubItem: Integer): TRect;
- var
- Rect: TRect;
- begin
- ListView_GetSubItemRect(LV_Handle, iItem, iSubItem, LVIR_LABEL, @Rect);
- Result := Rect;
- end;
- var
- PaintRect, r: TRect;
- i, iWidth, x, y: integer;
- S: string;
- begin
- try
- with lv do
- begin
- //LockPaint := True;
- PaintRect := GetItemRect(LV.Handle, Item.Index, SubItem);
- r := PaintRect;
- // if SubItem = DrawSubItem then
- Begin
- //这一段是算出百分比
- if Prosition >= Max then
- Prosition := 100
- else
- if Prosition <= 0 then
- Prosition := 0
- else
- Prosition := Round((Prosition / Max) * 100);
- if (Prosition = 0) and (not IsShowProgress) then
- begin
- //如果是百分比是0,就直接显示空白
- Canvas.FillRect(r);
- end
- else
- begin
- //先直充背景色
- Canvas.FillRect(r);
- Canvas.Brush.Color := Color;
- // Canvas.FillRect(r);
- //画一个外框
- InflateRect(r, -2, -2);
- Canvas.Brush.Color := FrameColor; //$00002F00;
- Canvas.FrameRect(R);
- Canvas.Brush.Color := Color;
- InflateRect(r, -1, -1);
- // Canvas.FillRect(r);
- InflateRect(r, -1, -1);
- //根据百分比算出要画的进度条内容宽度
- iWidth := R.Right - Round((R.Right - r.Left) * ((100 - Prosition) /
- 100));
- case Style of
- 0: //进度条类型,实心填充
- begin
- Canvas.Brush.Color := DrawColor;
- r.Right := iWidth;
- Canvas.FillRect(r);
- end;
- 1: //进度条类型,竖线填充
- begin
- i := r.Left;
- while i < iWidth do
- begin
- Canvas.Pen.Color := Color;
- Canvas.MoveTo(i, r.Top);
- Canvas.Pen.Color := DrawColor;
- canvas.LineTo(i, r.Bottom);
- Inc(i, 3);
- end;
- end;
- end;
- //画好了进度条后,现在要做的就是显示进度数字了
- Canvas.Brush.Style := bsClear;
- if Prosition = Round(Prosition) then
- S := Format('%d%%', [Round(Prosition)])
- else
- S := FormatFloat('#0.0', Prosition);
- with PaintRect do
- begin
- x := 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;
- except
- end;
- end;
- 上面是画进度条的,现在要给TlistView处理Item重绘的消息,事件是OnCustomDrawItem,需要说明的是,如果想要随心所欲的自画Item,那么就要全部自己来完成,不再需要系统来处理:
- procedure TForm1.ListView1CustomDrawItem(
- Sender: TCustomListView; Item: TListItem; State: TCustomDrawState;
- var DefaultDraw: Boolean);
- var
- BoundRect, Rect: TRect;
- i: integer;
- TextFormat: Word;
- LV: TListView;
- //这个子过程是用来画CheckBox和ImageList的
- procedure Draw_CheckBox_ImageList(r: TRect; aCanvas: TCanvas; Checked: Boolean);
- var
- R1: TRect;
- i: integer;
- begin
- if Sender.Checkboxes then
- begin
- aCanvas.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
- begin //画CheckBox的勾
- aCanvas.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 := PDownLoadListItem(Item.Data)^.StatsImageIndex;
- if i > -1 then
- begin
- //获取图标的RECT
- if Boolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) then
- begin
- ImageList_Stats.Draw(LV.Canvas, R1.Left, R1.Top, i);
- if item.ImageIndex > -1 then
- LV.SmallImages.Draw(LV.Canvas, R1.Right + 2, R1.Top, item.ImageIndex);
- end;
- end;
- end;
- begin
- LV := ListView1;
- BoundRect := Item.DisplayRect(drBounds);
- InflateRect(BoundRect, -1, 0);
- //这个地方你可以根据自己的要求设置成想要的颜色,实现突出显示
- LV.Canvas.Font.Color := clBtnText;
- //查看是否是被选中
- if Item.Selected then
- begin
- if cdsFocused in State then
- begin
- LV.Canvas.Brush.Color := $00ECCCB9; // //clHighlight;
- end
- else
- begin
- LV.Canvas.Brush.Color := $00F8ECE5; //clSilver;
- end;
- end
- else
- begin
- if (Item.Index mod 2) = 0 then
- LV.Canvas.Brush.Color := clWhite
- else
- LV.Canvas.Brush.Color := $00F2F2F2;
- end;
- LV.Canvas.FillRect(BoundRect); //初始化背景
- for i := 0 to LV.Columns.Count - 1 do
- begin
- //获取SubItem的Rect
- ListView_GetSubItemRect(LV.Handle, Item.Index, i, LVIR_LABEL, @Rect);
- case LV.Columns.Alignment of
- taLeftJustify:
- TextFormat := 0;
- taRightJustify:
- TextFormat := DT_RIGHT;
- taCenter:
- TextFormat := DT_CENTER;
- end;
- case i of
- 0: //画Caption,0就是表示Caption,这不是Subitems[0]
- begin
- //先画选择框与图标
- Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked);
- //再画Caption的文字
- InflateRect(Rect, -(5 + ImageList_Stats.Width), 0); //向后移3个像素,避免被后面画线框时覆盖
- DrawText(
- LV.Canvas.Handle,
- PCHAR(Item.Caption),
- Length(Item.Caption),
- Rect,
- DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat);
- end;
- 1..MaxInt: //画Subitems
- begin
- if i - 1 = 2 then //显示状态条
- begin
- //开始处理进度条了,这个示例是第3栏显示进度条,可以自己随便定义
- DrawSubItem(TListView(Sender),
- item,
- i,
- StrToFloatDef(Item.SubItems[i - 1], 0),
- 100,
- 0,
- True,
- //这里用了一个Lable来选颜色,你自己可以使用一个变量来代替
- LableProgressColor.Color, //进度条外框颜色
- LableProgressColor.Color //进度条颜色
- );
- end
- else
- //画SubItem的文字
- if i - 1 <= Item.SubItems.Count - 1 then
- DrawText(
- LV.Canvas.Handle,
- PCHAR(Item.SubItems[i - 1]),
- Length(Item.SubItems[i - 1]),
- Rect,
- DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat);
- end;
- end;
- end;
- LV.Canvas.Brush.Color := clWhite;
- if Item.Selected then //画选中条外框
- begin
- if cdsFocused in State then//控件是否处于激活状态
- LV.Canvas.Brush.Color := $00DAA07A // $00E2B598; //clHighlight;
- else
- LV.Canvas.Brush.Color := $00E2B598; //$00DAA07A // clHighlight;
- LV.Canvas.FrameRect(BoundRect); //
- end;
- DefaultDraw := False; //不让系统画了
- with Sender.Canvas do
- if Assigned(Font.OnChange) then Font.OnChange(Font);
- end;
复制代码
- function ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;
- begin
- Result := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex);
- end;
- //使用:
- item:=ListView1.Selected;
- item.subitems[1]:=30;//设置为30%
- //然后刷新这个item
- ReDrawItem(ListView1.handle,Item.index);
复制代码
不用进度条时的效果图:
不用进度条时的效果图
|
|