宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 2838|回复: 0

[分享] 自画TlistView带进度条的Item

[复制链接]
  • TA的每日心情
    开心
    2024-12-9 18:45
  • 签到天数: 124 天

    [LV.7]常住居民III

    admin 发表于 2009-12-3 00:09:36 | 显示全部楼层 |阅读模式

    欢迎您注册加入!这里有您将更精采!

    您需要 登录 才可以下载或查看,没有账号?注册

    x

    TListViewItem条一般是由系统自画的,但电驴就实现了自画,使之看起来很漂亮,我们用DELPHI也可以实现!

    1.jpg

    首先要引用CommCtrl单元,这是TListView底层控制单元:


    1. uses

    2. CommCtrl;

    3. //画状态条
    4. procedure DrawSubItem(LV: TListView; Item: TListItem; SubItem: Integer;
    5. Prosition: Single; Max, Style: Integer; IsShowProgress: Boolean;
    6. DrawColor: TColor = $00005B00;
    7. FrameColor: TColor = $00002F00);
    8. //获取SubItem的区域

    9. function GetItemRect(LV_Handle, iItem, iSubItem: Integer): TRect;

    10. var

    11. Rect: TRect;

    12. begin

    13. ListView_GetSubItemRect(LV_Handle, iItem, iSubItem, LVIR_LABEL, @Rect);
    14.     Result := Rect;

    15. end;
    16. var

    17. PaintRect, r: TRect;
    18. i, iWidth, x, y: integer;
    19. S: string;
    20. begin
    21. try


    22.     with lv do
    23.     begin

    24. //LockPaint := True;

    25. PaintRect := GetItemRect(LV.Handle, Item.Index, SubItem);
    26.      r := PaintRect;
    27. //      if SubItem = DrawSubItem then

    28. Begin
    29.         //这一段是算出百分比
    30.         if Prosition >= Max then

    31. Prosition := 100

    32. else
    33.           if Prosition <= 0 then

    34. Prosition := 0

    35. else

    36. Prosition := Round((Prosition / Max) * 100);


    37. if (Prosition = 0) and (not IsShowProgress) then
    38.         begin
    39.         //如果是百分比是0,就直接显示空白

    40. Canvas.FillRect(r);


    41. end
    42.         else
    43.         begin
    44.         //先直充背景色

    45. Canvas.FillRect(r);
    46.           Canvas.Brush.Color := Color;
    47. //          Canvas.FillRect(r);

    48.         //画一个外框

    49. InflateRect(r, -2, -2);
    50.           Canvas.Brush.Color := FrameColor; //$00002F00;

    51. Canvas.FrameRect(R);

    52.           Canvas.Brush.Color := Color;
    53.           InflateRect(r, -1, -1);
    54. //          Canvas.FillRect(r);


    55. InflateRect(r, -1, -1);
    56.         //根据百分比算出要画的进度条内容宽度
    57.           iWidth := R.Right - Round((R.Right - r.Left) * ((100 - Prosition) /

    58. 100));

    59. case Style of

    60. 0: //进度条类型,实心填充

    61. begin

    62. Canvas.Brush.Color := DrawColor;
    63.                 r.Right := iWidth;
    64.                 Canvas.FillRect(r);

    65. end;

    66. 1: //进度条类型,竖线填充

    67. begin

    68. i := r.Left;

    69. while i < iWidth do
    70.                 begin

    71. Canvas.Pen.Color := Color;
    72.                   Canvas.MoveTo(i, r.Top);
    73.                   Canvas.Pen.Color := DrawColor;
    74.                   canvas.LineTo(i, r.Bottom);
    75.                   Inc(i, 3);

    76. end;

    77. end;

    78. end;
    79. //画好了进度条后,现在要做的就是显示进度数字了
    80.           Canvas.Brush.Style := bsClear;

    81. if Prosition = Round(Prosition) then

    82. S := Format('%d%%', [Round(Prosition)])

    83. else

    84. S := FormatFloat('#0.0', Prosition);


    85. with PaintRect do
    86.           begin

    87. x := Left + (Right - Left + 1 - Canvas.TextWidth(S)) div 2;
    88.             y := Top + (Bottom - Top + 1 - Canvas.TextHeight(S)) div 2;

    89. end;
    90.           SetBkMode(Canvas.handle, TRANSPARENT);
    91.           Canvas.TextRect(PaintRect, x, y, S);


    92. end;
    93. //进度条全部画完,把颜色设置成默认色了
    94.         Canvas.Brush.Color := Color;


    95. end
    96.     end;

    97. except

    98. end;
    99. end;


    100. 上面是画进度条的,现在要给TlistView处理Item重绘的消息,事件是OnCustomDrawItem,需要说明的是,如果想要随心所欲的自画Item,那么就要全部自己来完成,不再需要系统来处理:
    101. procedure TForm1.ListView1CustomDrawItem(
    102. Sender: TCustomListView; Item: TListItem; State: TCustomDrawState;

    103. var DefaultDraw: Boolean);
    104. var

    105. BoundRect, Rect: TRect;
    106. i: integer;
    107. TextFormat: Word;
    108. LV: TListView;

    109. //这个子过程是用来画CheckBox和ImageList的

    110. procedure Draw_CheckBox_ImageList(r: TRect; aCanvas: TCanvas; Checked: Boolean);

    111. var

    112. R1: TRect;
    113.     i: integer;

    114. begin
    115.     if Sender.Checkboxes then
    116.     begin

    117. aCanvas.Pen.Color := clBlack;
    118.       aCanvas.Pen.Width := 2;

    119. //画CheckBox外框

    120. aCanvas.Rectangle(r.Left + 2, r.Top + 2, r.Left + 14, r.Bottom - 2);

    121. if Checked then
    122.       begin //画CheckBox的勾

    123. aCanvas.MoveTo(r.Left + 4, r.Top + 6);
    124.         aCanvas.LineTo(r.Left + 6, r.Top + 11);
    125.         aCanvas.LineTo(r.Left + 11, r.Top + 5);

    126. end;
    127.       aCanvas.Pen.Width := 1;

    128. end;

    129. //开始画图标

    130. i := PDownLoadListItem(Item.Data)^.StatsImageIndex;

    131. if i > -1 then
    132.     begin

    133. //获取图标的RECT

    134. if Boolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) then
    135.       begin

    136. ImageList_Stats.Draw(LV.Canvas, R1.Left, R1.Top, i);

    137. if item.ImageIndex > -1 then

    138. LV.SmallImages.Draw(LV.Canvas, R1.Right + 2, R1.Top, item.ImageIndex);

    139. end;


    140. end;

    141. end;
    142. begin

    143. LV := ListView1;
    144. BoundRect := Item.DisplayRect(drBounds);
    145. InflateRect(BoundRect, -1, 0);

    146. //这个地方你可以根据自己的要求设置成想要的颜色,实现突出显示

    147. LV.Canvas.Font.Color := clBtnText;

    148. //查看是否是被选中

    149. if Item.Selected then
    150. begin
    151.     if cdsFocused in State then
    152.     begin

    153. LV.Canvas.Brush.Color := $00ECCCB9; // //clHighlight;

    154. end
    155.     else
    156.     begin

    157. LV.Canvas.Brush.Color := $00F8ECE5; //clSilver;

    158. end;

    159. end
    160. else
    161. begin
    162.     if (Item.Index mod 2) = 0 then

    163. LV.Canvas.Brush.Color := clWhite

    164. else

    165. LV.Canvas.Brush.Color := $00F2F2F2;

    166. end;

    167. LV.Canvas.FillRect(BoundRect); //初始化背景


    168. for i := 0 to LV.Columns.Count - 1 do
    169. begin

    170. //获取SubItem的Rect

    171. ListView_GetSubItemRect(LV.Handle, Item.Index, i, LVIR_LABEL, @Rect);

    172. case LV.Columns.Alignment of

    173. taLeftJustify:
    174.         TextFormat := 0;
    175.       taRightJustify:
    176.         TextFormat := DT_RIGHT;
    177.       taCenter:
    178.         TextFormat := DT_CENTER;

    179. end;

    180. case i of

    181. 0: //画Caption,0就是表示Caption,这不是Subitems[0]

    182. begin
    183. //先画选择框与图标

    184. Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked);
    185. //再画Caption的文字
    186.           InflateRect(Rect, -(5 + ImageList_Stats.Width), 0); //向后移3个像素,避免被后面画线框时覆盖

    187. DrawText(
    188.             LV.Canvas.Handle,
    189.             PCHAR(Item.Caption),
    190.             Length(Item.Caption),
    191.             Rect,
    192.             DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat);

    193. end;

    194. 1..MaxInt: //画Subitems

    195. begin
    196.           if i - 1 = 2 then //显示状态条

    197. begin
    198. //开始处理进度条了,这个示例是第3栏显示进度条,可以自己随便定义

    199. DrawSubItem(TListView(Sender),
    200.               item,
    201.               i,
    202.               StrToFloatDef(Item.SubItems[i - 1], 0),

    203. 100,

    204. 0,
    205.               True,
    206. //这里用了一个Lable来选颜色,你自己可以使用一个变量来代替
    207.              LableProgressColor.Color, //进度条外框颜色

    208. LableProgressColor.Color //进度条颜色
    209. );


    210. end
    211.           else
    212. //画SubItem的文字
    213.             if i - 1 <= Item.SubItems.Count - 1 then

    214. DrawText(
    215.                 LV.Canvas.Handle,
    216.                 PCHAR(Item.SubItems[i - 1]),
    217.                 Length(Item.SubItems[i - 1]),
    218.                 Rect,
    219.                 DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat);




    220. end;

    221. end;


    222. end;


    223. LV.Canvas.Brush.Color := clWhite;


    224. if Item.Selected then //画选中条外框

    225. begin
    226.     if cdsFocused in State then//控件是否处于激活状态

    227. LV.Canvas.Brush.Color := $00DAA07A // $00E2B598; //clHighlight;

    228. else

    229. LV.Canvas.Brush.Color := $00E2B598; //$00DAA07A // clHighlight;

    230. LV.Canvas.FrameRect(BoundRect); //

    231. end;

    232. DefaultDraw := False; //不让系统画了


    233. with Sender.Canvas do
    234.     if Assigned(Font.OnChange) then Font.OnChange(Font);



    235. end;
    复制代码


    1. function ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;
    2. begin
    3.   Result := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex);
    4. end;
    5. //使用:
    6. item:=ListView1.Selected;
    7. item.subitems[1]:=30;//设置为30%
    8. //然后刷新这个item
    9. ReDrawItem(ListView1.handle,Item.index);
    复制代码

    不用进度条时的效果图:

    不用进度条时的效果图

    不用进度条时的效果图

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

    本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

    QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

    Copyright © 2001-2023 Discuz! Team. GMT+8, 2024-12-22 20:56 , File On Powered by Discuz! X3.49

    快速回复 返回顶部 返回列表