ListView 实现进度条显示

代码参考互联网,本人在Win10 + Delphi 10.3.2 社区版中测试通过,现将测试通过的代码分享如下:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
System.ImageList, Vcl.ImgList;
type
TForm1 = class(TForm)
lv1: TListView;
btn1: TButton;
procedure lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem;
State: TCustomDrawState; var DefaultDraw: Boolean);
procedure btn1Click(Sender: TObject);
private
procedure DrawSubItem(ALV: TListView; AItem: TListItem; ASubItem: Integer;
APosition: Single; AMax, AStyle: Integer; AIsShowProgress: Boolean;
ADrawColor: TColor = $00005B00; AFrameColor: TColor = $00002F00);
function ReDrawItem(AHwndLV: HWND; AItemIndex: integer): boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Winapi.CommCtrl;
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
NewColumn: TListColumn;
NewItem: TListItem;
i: Integer;
begin
lv1.Items.Clear;
lv1.Columns.Clear;
NewColumn := lv1.Columns.Add; NewColumn.Caption := '名称';
NewColumn := lv1.Columns.Add; NewColumn.Caption := '进度';
NewColumn := lv1.Columns.Add; NewColumn.Caption := '进度条';
for I := 0 to 10 do
begin
NewItem := lv1.Items.Add;
NewItem.Caption := IntToStr(i);
NewItem.SubItems.Add(IntToStr(i * 10));
NewItem.SubItems.Add(IntToStr(i * 10));
end;
end;
procedure TForm1.DrawSubItem(ALV: TListView; AItem: TListItem; ASubItem: Integer;
APosition: Single; AMax, AStyle: Integer; AIsShowProgress: Boolean;
ADrawColor: TColor = $00005B00; AFrameColor: TColor = $00002F00);
var
PaintRect, r: TRect;
i, iWidth, x, y: integer;
S: string;
function GetItemRect(LV_Handle, iItem, iSubItem: Integer): TRect;
var
Rect: TRect;
begin
ListView_GetSubItemRect(LV_Handle, iItem, iSubItem, LVIR_LABEL, @Rect);
Result := Rect;
end;
begin
with ALV do
begin
PaintRect := GetItemRect(ALV.Handle, AItem.Index, ASubItem);
r := PaintRect;
//这一段是算出百分比
if APosition >= AMax then
APosition := 100
else
if APosition <= 0 then
APosition := 0
else
APosition := Round((APosition / AMax) * 100);
if (APosition = 0) and (not AIsShowProgress) then
begin
//如果是百分比是0,就直接显示空白
Canvas.FillRect(r);
end else begin
//先直充背景色
Canvas.FillRect(r);
Canvas.Brush.Color := Color;
//画一个外框
InflateRect(r, -2, -2);
Canvas.Brush.Color := AFrameColor; //$00002F00;
Canvas.FrameRect(R);
Canvas.Brush.Color := Color;
InflateRect(r, -1, -1);
InflateRect(r, -1, -1);
//根据百分比算出要画的进度条内容宽度
iWidth := R.Right - Round((R.Right - r.Left) * ((100 - APosition) / 100));
case AStyle of
0: //进度条类型,实心填充
begin
Canvas.Brush.Color := ADrawColor;
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 := ADrawColor;
canvas.LineTo(i, r.Bottom);
Inc(i, 3);
end;
end;
end;
//画好了进度条后,现在要做的就是显示进度数字了
Canvas.Brush.Style := bsClear;
if APosition = Round(APosition) then
S := Format('%d%%', [Round(APosition)])
else
S := FormatFloat('#0.0', APosition);
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; // end of if (Prosition = 0) and (not IsShowProgress) then
//进度条全部画完,把颜色设置成默认色了
Canvas.Brush.Color := Color;
end; // end of with LV do
end;
procedure TForm1.lv1CustomDrawItem(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 //画CheckBox的钩
// begin
// 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 := 2; //ImageIndex的值,可以任意
// 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 := TListView(Sender);
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[i].Alignment of
taLeftJustify:
TextFormat := DT_LEFT;
taRightJustify:
TextFormat := DT_RIGHT;
taCenter:
TextFormat := DT_CENTER;
else
TextFormat := DT_CENTER;
end;
case i of
0: //画Caption,0表示Caption,不是Subitem
begin
//先画选择框和图标
//Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked);
InflateRect(Rect, -(5 + 0), 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: //画SubItem[i]
begin
if (i - 1) = 1 then //显示状态条,本示例是第三栏显示,
begin
DrawSubItem(LV, Item, i, StrToFloatDef(Item.SubItems[i - 1], 0), 100, 0, True, clMedGray);
end
else
begin
//画SubItem的文字
InflateRect(Rect, -2, -2);
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; //end case
end; //end for
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 TForm1.ReDrawItem(AHwndLV: HWND; AItemIndex: integer): boolean;
begin
Result := ListView_RedrawItems(AHwndLV, AItemIndex, AItemIndex);
end;
end.
ListView 实现进度条显示的更多相关文章
- 【Winform】使用BackgroundWorker控制进度条显示进度
许多开发者看见一些软件有进度条显示进度,自己想弄,项目建好后发现并没有自己想象中的那么简单...看了网上很多教程后,写了一个小Demo供网友们参考~~,Demo的网址:http://pan.baidu ...
- Extjs 使用fileupload插件上传文件 带进度条显示
一.首先我们看看官方给出的插件的解释: 一个文件上传表单项具有自定义的样式,并且可以控制按钮的文本和 像文本表单的空文本类似的其他特性. 它使用一个隐藏的文件输入元素,并在用户选择文件后 在form提 ...
- Ajax上传文件进度条显示
要实现进度条的显示,就要知道两个参数,上传的大小和总文件的大小 html5提供了一个上传过程事件,在上传过程中不断触发,然后用已上传的大 小/总大小,计算上传的百分比,然后用这个百分比控制div框的显 ...
- 【Android】读取sdcard卡上的全部图片而且显示,读取的过程有进度条显示
尽管以下的app还没有做到快图浏览.ES文件浏览器的水平,遇到大sdcard还是会存在读取过久.内存溢出等问题,可是基本思想是这种. 例如以下图.在sdcard卡上有4张图片, 打开app,则会吧sd ...
- Qt flash_eraseall nandwrite 进度条显示擦除、烧录
/***************************************************************************** * Qt flash_eraseall n ...
- MFC读写.txt文件时进度条显示实时进度
整体实现方式:先获得文件长度,然后用每次读取的长度,计算出完成的百分比,用百分比的值设置进度条. 一.MFC进度条 Progress Control 相关函数 1. create() --创建Prog ...
- iOS 获取内存大小使用情况(进度条显示)
一.获取设备内存大小方法 //返回存储内存占用比例 - (NSString *)getFreeDiskspaceRate{ float totalSpace; .f; NSError *error = ...
- ajaxSubmit() 上传文件和进度条显示
1. 首先引用js文件 <script type="text/javascript" src="/js/jquery/jquery.form.js"&g ...
- Python 计算π及进度条显示
一,首先打开命令提示符找到Python路径,输入pip install tqdm下载第三方库tpdm. 二,写程序 法一 from math import * from tqdm import tqd ...
随机推荐
- iOS开发之--隐藏状态栏
1,全局隐藏 在Targets->General->勾选中Hide status bar .,如下图: 2.单个页面隐藏/展示状态栏 1).首先在info.plist里面View cont ...
- 数据挖掘--OPTICS
OPTICS是基于DBSCAN算法的缺陷提出来的一个算法. 核心思想:为每个数据对象计算出一个顺序值(ordering).这些值代表了数据对象的基于密度的族结构,位于同一个族的数据对象具有相近的顺序值 ...
- Invalid utf8mb4 character string: '"'
将CSV格式数据导入 mysql,报错: load data infile 'f:/nmg.csv' into table nmg fields terminated by ',' optionall ...
- emoji表情多终端适配解决方案
emoji表情多终端适配解决方案 emoji,也叫 颜表情 是日本在无线通信中所使用的视觉情感符号,由栗田穰崇(Shigetaka Kurita)创作,并在日本网络及手机用户中流行.自苹果公司发布的i ...
- JMETER 用户变量作用域
在编写JMETER 脚本时,我们会使用到变量,变量的作用域是线程. 我们通过下面的脚本验证一下变量的返回是线程. 1. 我们先定义一个amount的流程变量. 2.线程组使用三个线程 3.在线程组中添 ...
- 解决eclipse中maven多模块项目显示不全的问题
背景:在eclipse中导入maven项目,后来发现有的子模块不能正常的显示出现 原因:没有加载到子模块的pom文件 解决方法:重新导入:import-> 勾选项目->选择你缺少的项目的p ...
- linux (06) redis安装
redis安装 一.在linux安装redis,通过源码编译安装redis 1.下载源码包 wget http://download.redis.io/releases/redis-4.0.10.ta ...
- 两道DP,四年修一次路
第十一届:山区修路 题目描述 SNJ位于HB省西部一片群峰耸立的高大山地,横亘于A江.B水之间,方圆数千平方公里,相传上古的神医在此搭架上山采药而得名.景区山峰均在海拔3000米以上,堪称" ...
- 201871010125-王玉江《面向对象程序设计(java)》第十五周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ht ...
- 201871010108-高文利《面向对象程序设计(java)》第四周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ht ...