登录
|
注册
|
在线情况
|
搜索
|
帮助
爱者家园
→
电脑网络
→
VC编程交流
→
自画TlistView带进度条的Item(delphi)
本地收藏
QQ书签
百度搜藏
雅虎收藏
自画TlistView带进度条的Item(delphi)
发起人:
txiang
回复数:
0
浏览数:
11684
最后更新:2010/4/18 21:46:57 by
txiang
简洁模式
完整模式
选择查看
发表新帖
搜索更多相关主题
帖子排序:
从旧到新
从新到旧
查看 txiang 的资料
给 txiang 发送邮件
搜索 txiang 的帖子
2010/4/18 21:46:57
[
只看该作者
]
#1
txiang
角 色:注册用户
发 帖 数:31
经 验 值:62
注册时间:2007/8/6
联系
回复
编辑
删除
自画TlistView带进度条的Item(delphi)
自画TlistView带进度条的Item
- [
学习资料
]
<div class=postBody>
版权声明
:转载时请以超链接形式标明文章原始出处和作者信息及
本声明
http://proc.blogbus.com/logs/28162911.html
<div style="TEXT-INDENT: 21.75pt">TListView的Item条一般是由系统自画的,但电驴就实现了自画,使之看起来很漂亮,我们用DELPHI也可以实现!</div><div style="TEXT-INDENT: 21.75pt">
</div><div style="TEXT-INDENT: 21.75pt">首先要引用
CommCtrl
单元,这是
TListView底层控制单元:</div><div align=left>
uses
</div><div align=left>
CommCtrl;
</div><div align=left>
//
画状态条
</div><div align=left>
procedure
DrawSubItem(LV: TListView; Item: TListItem; SubItem: Integer;
</div><div align=left>
Prosition: Single; Max, Style: Integer; IsShowProgress: Boolean;
</div><div align=left>
DrawColor: TColor =
$00005B00
;
</div><div align=left>
FrameColor: TColor =
$00002F00
);
</div><div align=left>
//
获取
SubItem
的区域
</div><div align=left>
function
GetItemRect(LV_Handle, iItem, iSubItem: Integer): TRect;
</div><div align=left>
var
</div><div align=left>
Rect: TRect;
</div><div align=left>
begin
</div><div align=left>
ListView_GetSubItemRect(LV_Handle, iItem, iSubItem, LVIR_LABEL, @Rect);
</div><div align=left>
Result := Rect;
</div><div align=left>
end
;
</div><div align=left>
var
</div><div align=left>
PaintRect, r: TRect;
</div><div align=left>
i, iWidth, x, y: integer;
</div><div align=left>
S:
string
;
</div><div align=left>
begin
</div><div align=left>
try
</div><div align=left></div><div align=left>
with
lv
do
</div><div align=left>
begin
</div><div align=left>
//LockPaint := True;
</div><div align=left>
PaintRect := GetItemRect(LV.Handle, Item.Index, SubItem);
</div><div align=left>
r := PaintRect;
</div><div align=left>
// if SubItem = DrawSubItem then
</div><div align=left>
Begin
</div><div align=left>
//
这一段是算出百分比
</div><div align=left>
if
Prosition >= Max
then
</div><div align=left>
Prosition :=
100
</div><div align=left>
else
</div><div align=left>
if
Prosition <=
0
then
</div><div align=left>
Prosition :=
0
</div><div align=left>
else
</div><div align=left>
Prosition := Round((Prosition / Max) *
100
);
</div><div align=left>
if
(Prosition =
0
)
and
(
not
IsShowProgress)
then
</div><div align=left>
begin
</div><div align=left>
//
如果是百分比是
0
,就直接显示空白
</div><div align=left>
Canvas.FillRect(r);
</div><div align=left>
end
</div><div align=left>
else
</div><div align=left>
begin
</div><div align=left>
//
先直充背景色
</div><div align=left>
Canvas.FillRect(r);
</div><div align=left>
Canvas.Brush.Color := Color;
</div><div align=left>
// Canvas.FillRect(r);
</div><div align=left>
//
画一个外框
</div><div align=left>
InflateRect(r, -
2
, -
2
);
</div><div align=left>
Canvas.Brush.Color := FrameColor;
//$00002F00;
</div><div align=left>
Canvas.FrameRect(R);
</div><div align=left>
Canvas.Brush.Color := Color;
</div><div align=left>
InflateRect(r, -
1
, -
1
);
</div><div align=left>
// Canvas.FillRect(r);
</div><div align=left>
InflateRect(r, -
1
, -
1
);
</div><div align=left>
//
根据百分比算出要画的进度条内容宽度
</div><div align=left>
iWidth := R.Right - Round((R.Right - r.Left) * ((
100
- Prosition) /
</div><div align=left>
100
));
</div><div align=left>
case
Style
of
</div><div align=left>
0
:
//
进度条类型,实心填充
</div><div align=left>
begin
</div><div align=left>
Canvas.Brush.Color := DrawColor;
</div><div align=left>
r.Right := iWidth;
</div><div align=left>
Canvas.FillRect(r);
</div><div align=left>
end
;
</div><div align=left>
1
:
//
进度条类型,竖线填充
</div><div align=left>
begin
</div><div align=left>
i := r.Left;
</div><div align=left>
while
i < iWidth
do
</div><div align=left>
begin
</div><div align=left>
Canvas.Pen.Color := Color;
</div><div align=left>
Canvas.MoveTo(i, r.Top);
</div><div align=left>
Canvas.Pen.Color := DrawColor;
</div><div align=left>
canvas.LineTo(i, r.Bottom);
</div><div align=left>
Inc(i,
3
);
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div style="TEXT-INDENT: 45pt" align=left>
//
画好了进度条后,现在要做的就是显示进度数字了
</div><div align=left>
Canvas.Brush.Style := bsClear;
</div><div align=left>
if
Prosition = Round(Prosition)
then
</div><div align=left>
S := Format(
'%d%%'
, [Round(Prosition)])
</div><div align=left>
else
</div><div align=left>
S := FormatFloat(
'#0.0'
, Prosition);
</div><div align=left>
with
PaintRect
do
</div><div align=left>
begin
</div><div align=left>
x := Left + (Right - Left +
1
- Canvas.TextWidth(S))
div
2
;
</div><div align=left>
y := Top + (Bottom - Top +
1
- Canvas.TextHeight(S))
div
2
;
</div><div align=left>
end
;
</div><div align=left>
SetBkMode(Canvas.handle, TRANSPARENT);
</div><div align=left>
Canvas.TextRect(PaintRect, x, y, S);
</div><div align=left>
end
;
</div><div style="TEXT-INDENT: 36pt" align=left>
//
进度条全部画完,把颜色设置成默认色了
</div><div align=left>
Canvas.Brush.Color := Color;
</div><div align=left>
end
</div><div align=left>
end
;
</div><div align=left>
except
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div align=left>
上面是画进度条的,现在要给
TlistView
处理
Item
重绘的消息,事件是
On
CustomDrawItem
,
需要说明的是,如果想要随心所欲的自画
Item
,那么就要全部自己来完成,不再需要系统来处理:
</div><div align=left>
procedure
TForm1.ListView1CustomDrawItem(
</div><div align=left>
Sender: TCustomListView; Item: TListItem; State: TCustomDrawState;
</div><div align=left>
var
DefaultDraw: Boolean);
</div><div align=left>
var
</div><div align=left>
BoundRect, Rect: TRect;
</div><div align=left>
i: integer;
</div><div align=left>
TextFormat: Word;
</div><div align=left>
LV: TListView;
</div><div align=left>
//
这个子过程是用来画
CheckBox
和
ImageList
的
</div><div align=left>
procedure
Draw_CheckBox_ImageList(r: TRect; aCanvas: TCanvas; Checked: Boolean);
</div><div align=left>
var
</div><div align=left>
R1: TRect;
</div><div align=left>
i: integer;
</div><div align=left>
begin
</div><div align=left>
if
Sender.Checkboxes
then
</div><div align=left>
begin
</div><div align=left>
aCanvas.Pen.Color := clBlack;
</div><div align=left>
aCanvas.Pen.Width :=
2
;
</div><div align=left>
//
画
CheckBox
外框
</div><div align=left>
aCanvas.Rectangle(r.Left +
2
, r.Top +
2
, r.Left +
14
, r.Bottom -
2
);
</div><div align=left>
if
Checked
then
</div><div align=left>
begin
//
画
CheckBox
的勾
</div><div align=left>
aCanvas.MoveTo(r.Left +
4
, r.Top +
6
);
</div><div align=left>
aCanvas.LineTo(r.Left +
6
, r.Top +
11
);
</div><div align=left>
aCanvas.LineTo(r.Left +
11
, r.Top +
5
);
</div><div align=left>
end
;
</div><div align=left>
aCanvas.Pen.Width :=
1
;
</div><div align=left>
end
;
</div><div align=left>
//
开始画图标
</div><div align=left>
i := PDownLoadListItem(Item.Data)^.StatsImageIndex;
</div><div align=left>
if
i > -
1
then
</div><div align=left>
begin
</div><div align=left>
//
获取图标的
RECT
</div><div align=left>
if
Boolean(ListView_GetSubItemRect(sender.Handle, item.Index,
0
, LVIR_ICON, @R1))
then
</div><div align=left>
begin
</div><div align=left>
ImageList_Stats.Draw(LV.Canvas, R1.Left, R1.Top, i);
</div><div align=left>
if
item.ImageIndex > -
1
then
</div><div align=left>
LV.SmallImages.Draw(LV.Canvas, R1.Right +
2
, R1.Top, item.ImageIndex);
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div align=left>
begin
</div><div align=left>
LV
:= ListView1;
</div><div align=left>
BoundRect := Item.DisplayRect(drBounds);
</div><div align=left>
InflateRect(BoundRect, -
1
,
0
);
</div><div align=left>
//
这个地方你可以根据自己的要求设置成想要的颜色,实现突出显示
</div><div align=left>
LV.Canvas.Font.Color := clBtnText;
</div><div align=left>
//
查看是否是被选中
</div><div align=left>
if
Item.Selected
then
</div><div align=left>
begin
</div><div align=left>
if
cdsFocused
in
State
then
</div><div align=left>
begin
</div><div align=left>
LV.Canvas.Brush.Color :=
$00ECCCB9
;
// //clHighlight;
</div><div align=left>
end
</div><div align=left>
else
</div><div align=left>
begin
</div><div align=left>
LV.Canvas.Brush.Color :=
$00F8ECE5
;
//clSilver;
</div><div align=left>
end
;
</div><div align=left>
end
</div><div align=left>
else
</div><div align=left>
begin
</div><div align=left>
if
(Item.Index
mod
2
) =
0
then
</div><div align=left>
LV.Canvas.Brush.Color := clWhite
</div><div align=left>
else
</div><div align=left>
LV.Canvas.Brush.Color :=
$00F2F2F2
;
</div><div align=left>
end
;
</div><div align=left>
LV.Canvas.FillRect(BoundRect);
//
初始化背景
</div><div align=left>
for
i :=
0
to
LV.Columns.Count -
1
do
</div><div align=left>
begin
</div><div align=left>
//
获取
SubItem
的
Rect
</div><div align=left>
ListView_GetSubItemRect(LV.Handle, Item.Index, i, LVIR_LABEL, @Rect);
</div><div align=left>
case
LV.Columns
.Alignment
of
</div><div align=left>
taLeftJustify:
</div><div align=left>
TextFormat :=
0
;
</div><div align=left>
taRightJustify:
</div><div align=left>
TextFormat := DT_RIGHT;
</div><div align=left>
taCenter:
</div><div align=left>
TextFormat := DT_CENTER;
</div><div align=left>
end
;
</div><div align=left>
case
i
of
</div><div align=left>
0
:
//
画
Caption
,
0
就是表示
Caption
,这不是
Subitems[0]
</div><div align=left>
begin
</div><div style="TEXT-INDENT: 45pt" align=left>
//
先画选择框与图标
</div><div align=left>
Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked);
</div><div style="TEXT-INDENT: 45pt" align=left>
//
再画
Caption
的文字
</div><div align=left>
InflateRect(Rect, -(
5
+ ImageList_Stats.Width),
0
);
//
向后移
3
个像素
,
避免被后面画线框时覆盖
</div><div align=left>
DrawText(
</div><div align=left>
LV.Canvas.Handle,
</div><div align=left>
PCHAR(Item.Caption),
</div><div align=left>
Length(Item.Caption),
</div><div align=left>
Rect,
</div><div align=left>
DT_VCENTER
or
DT_SINGLELINE
or
DT_END_ELLIPSIS
or
TextFormat);
</div><div align=left>
end
;
</div><div align=left>
1
..MaxInt:
//
画
Subitems
</div><div align=left>
begin
</div><div align=left>
if
i -
1
=
2
then
//
显示状态条
</div><div align=left>
begin
</div><div style="TEXT-INDENT: 45pt" align=left>
//
开始处理进度条了,这个示例是第
3
栏显示进度条,可以自己随便定义
</div><div align=left>
DrawSubItem(TListView(Sender),
</div><div align=left>
item,
</div><div align=left>
i,
</div><div align=left>
StrToFloatDef(Item.SubItems[i -
1
],
0
),
</div><div align=left>
100
,
</div><div align=left>
0
,
</div><div align=left>
True,
</div><div style="TEXT-INDENT: 45pt" align=left>
//
这里用了一个
Lable
来选颜色,你自己可以使用一个变量来代替
</div><div align=left>
LableProgressColor.Color,
//
进度条外框颜色
</div><div align=left>
LableProgressColor.Color
//
进度条颜色
</div><div style="TEXT-INDENT: 63pt" align=left>
);
</div><div align=left>
end
</div><div align=left>
else
</div><div style="TEXT-INDENT: 45pt" align=left>
//
画
SubItem
的文字
</div><div align=left>
if
i -
1
<= Item.SubItems.Count -
1
then
</div><div align=left>
DrawText(
</div><div align=left>
LV.Canvas.Handle,
</div><div align=left>
PCHAR(Item.SubItems[i -
1
]),
</div><div align=left>
Length(Item.SubItems[i -
1
]),
</div><div align=left>
Rect,
</div><div align=left>
DT_VCENTER
or
DT_SINGLELINE
or
DT_END_ELLIPSIS
or
TextFormat);
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div align=left>
end
;
</div><div align=left>
LV.Canvas.Brush.Color := clWhite;
</div><div align=left>
if
Item.Selected
then
//
画选中条外框
</div><div align=left>
begin
</div><div align=left>
if
cdsFocused
in
State
then
//
控件是否处于激活状态
</div><div align=left>
LV.Canvas.Brush.Color :=
$00DAA07A
// $00E2B598; //clHighlight;
</div><div align=left>
else
</div><div align=left>
LV.Canvas.Brush.Color :=
$00E2B598
;
//$00DAA07A // clHighlight;
</div><div align=left>
LV.Canvas.FrameRect(BoundRect);
//
</div><div align=left>
end
;
</div><div align=left>
DefaultDraw := False;
//
不让系统画了
</div><div align=left>
with
Sender.Canvas
do
</div><div align=left>
if
Assigned(Font.OnChange)
then
Font.OnChange(Font);
</div><div align=left>
end
;
</div><div align=left></div><div align=left>
function ReDrawItem(HwndLV: HWND; ItemIndex: integer): boolean;
begin
Result := ListView_RedrawItems(HwndLV, ItemIndex, ItemIndex);
end;
</div><div align=left></div><div align=left>
//使用:
</div><div align=left>
item:=ListView1.Selected;
</div><div align=left>
item.subitems[1]:='30';//设置为30%
</div><div align=left>
//然后刷新这个item
ReDrawItem(ListView1.handle,Item.index);
<div style="TEXT-INDENT: 21.75pt">不用进度条时的效果图:</div><div style="TEXT-INDENT: 21.75pt" align=center>
</div></div></div>
联系我们
-
sieye
-
论坛存档
-
返回顶部
Powered by
BBSXP 2008 SP2 ACCESS
© 1998-2024
Yuzi.Net
Processed in 0.05 second(s)
Server Time 2024/11/27 1:14:41