delphi listview自绘图形显示进度条 分颜色显示
- 格式:doc
- 大小:15.62 KB
- 文档页数:15
delphi listview自绘图形显示进度条分颜色显示delphi listview自绘图形显示进度条分颜色显示2011-05-30 10:31delphi listview自绘图形显示进度条自画TlistView带进度条的ItemTListView的Item条一般是由系统自画的,但电驴就实现了自画,使之看起来很漂亮,我们用DELPHI也可以实现!首先要引用CommCtrl单元,这是TListView底层控制单元:usesCommCtrl;//画状态条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;varRect: TRect;beginListView_GetSubItemRect(LV_Handle, iItem, iSubItem, LVIR_LABEL, @Rect);Result := Rect;end;varPaintRect, r: TRect;i, iWidth, x, y: integer;S: string;begintrywith lv dobegin//LockPaint := True;PaintRect := GetItemRect(LV.Handle, Item.Index, SubItem);r := PaintRect;// if SubItem = DrawSubItem thenBegin//这一段是算出百分比if Prosition >= Max thenProsition := 100elseif Prosition <= 0 thenProsition := 0elseProsition := Round((Prosition / Max) * 100);if (Prosition = 0) and (not IsShowProgress) thenbegin//如果是百分比是0,就直接显示空白Canvas.FillRect(r);endelsebegin//先直充背景色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 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;//画好了进度条后,现在要做的就是显示进度数字了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;endend;exceptend;end;上面是画进度条的,现在要给TlistView处理Item重绘的消息,事件是OnCustomDrawItem,需要说明的是,如果想要随心所欲的自画Item,那么就要全部自己来完成,不再需要系统来处理:procedure TForm1.ListView1CustomDrawItem(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: Boolean);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 thenbegin //画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 thenbegin//获取图标的RECTifBoolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) thenbeginImageList_Stats.Draw(LV.Canvas, R1.Left,R1.Top, i);if item.ImageIndex > -1 thenLV.SmallImages.Draw(LV.Canvas, R1.Right + 2, R1.Top, item.ImageIndex);end;end;end;beginLV := ListView1;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.Canvas.FillRect(BoundRect); //初始化背景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 := 0;taRightJustify:TextFormat := DT_RIGHT;taCenter:TextFormat := DT_CENTER;end;case i of0: //画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 orDT_END_ELLIPSIS or TextFormat);end;1..MaxInt: //画Subitems[i]beginif 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 //进度条颜色);endelse//画SubItem的文字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 or DT_END_ELLIPSIS or TextFormat);end;end;end;LV.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 ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;beginResult := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex);end;//使用:item:=ListView1.Selected;item.subitems[1]:='30';//设置为30%//然后刷新这个itemReDrawItem(ListView1.handle,Item.index);不用进度条时的效果图:。