起源:

重回DC5项目,资源下载美工提供圆形进度条,复习Delphi,为实现其颇觉有趣,遂研究其。

最终效果图如下:

实现:

制作TCircleProgress控件,实现方法参照系统之TGauge控件,CSDN上tp机器猫一个源码,结合GDI+绘制技术实现以消除锯齿,以Bitmap Copy技术以避免闪烁。

设计控件图标时,Delphi7自带之Image Editor在之后版本中没了,重装其取出来用。水平问题,设计亦十分粗糙。

直贴源码吧,源码及Demo可在下面下载。

{*******************************************************}
{ }
{ 圆形进度条,使用到GDIPlus技术 }
{ }
{ 刘景威 2018 }
{ }
{*******************************************************} unit CircleProgress; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms; const
FORE_COLOR = clTeal;
BACK_COLOR = clSilver;
PEN_WIDTH = ; type
TCircleProgress = class(TGraphicControl)
private
{ Private declarations }
FMinValue: Longint;
FMaxValue: Longint;
FCurValue: Longint;
FPenWidth: Integer;
FShowText: Boolean;
FForeColor: TColor;
FBackColor: TColor;
FFullCover: Boolean; procedure SetShowText(const Value: Boolean);
procedure SetForeColor(const Value: TColor);
procedure SetBackColor(const Value: TColor);
procedure SetFullCover(const Value: Boolean);
procedure SetMinValue(const Value: Longint);
procedure SetMaxValue(const Value: Longint);
procedure SetProgress(const Value: Longint);
procedure SetPenWidth(const Value: Integer);
//绘制
procedure DrawBackground(const ACanvas: TCanvas);
procedure DrawProgress(const ACanvas: TCanvas);
protected
{ Protected declarations }
procedure Paint; override;
procedure Resize; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
published
property Align;
property Anchors;
property BackColor: TColor read FBackColor write SetBackColor default BACK_COLOR;
property FullCover: Boolean read FFullCover write SetFullCover default False;
property Color;
property Constraints;
property Enabled;
property ForeColor: TColor read FForeColor write SetForeColor default FORE_COLOR;
property Font;
property MinValue: Longint read FMinValue write SetMinValue default ;
property MaxValue: Longint read FMaxValue write SetMaxValue default ;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PenWidth: Integer read FPenWidth write SetPenWidth;
property PopupMenu;
property Progress: Longint read FCurValue write SetProgress;
property ShowHint;
property ShowText: Boolean read FShowText write SetShowText default True;
property Visible;
end; procedure Register; implementation uses
Math, Consts, GDIPOBJ, GDIPAPI; procedure Register;
begin
RegisterComponents('Samples', [TCircleProgress]);
end; { TCircleProgress } constructor TCircleProgress.Create(AOwner: TComponent);
begin
inherited Create(AOwner); ControlStyle := ControlStyle + [csFramed, csOpaque];
{ default values }
FMinValue := ;
FMaxValue := ;
FCurValue := ;
FShowText := True;
FForeColor := FORE_COLOR;
FBackColor := BACK_COLOR;
FPenWidth := PEN_WIDTH;
Width := ;
Height := ;
end; procedure TCircleProgress.DrawBackground(const ACanvas: TCanvas);
var
g: TGPGraphics;
p: TGPPen;
r: TGPRectF;
pw: Integer;
begin
//背景
ACanvas.Brush.Color := Self.Color;
ACanvas.FillRect(Self.ClientRect); //轨道
g := TGPGraphics.Create(ACanvas.Handle);
pw := FPenWidth;
if not FFullCover then
Inc(pw, );
p := TGPPen.Create(ColorRefToARGB(FBackColor), pw);
try
r := MakeRect(pw / , pw / , Self.Width - pw - , Self.Height - pw - );
g.SetSmoothingMode(SmoothingModeAntiAlias);
g.DrawEllipse(p, r);
finally
p.Free;
g.Free;
end;
end; procedure TCircleProgress.DrawProgress(const ACanvas: TCanvas);
procedure DrawPercent(g: TGPGraphics);
var
percent: Integer;
sb: TGPSolidBrush;
fm: TGPFontFamily;
f: TGPFont;
sf: TGPStringFormat;
begin
percent := Round(FCurValue * / (FMaxValue - FMinValue));
sb := TGPSolidBrush.Create(ColorRefToARGB(Font.Color));
fm := TGPFontFamily.Create(Self.Font.Name);
f := TGPFont.Create(fm, Self.Font.Size, FontStyleRegular, UnitPoint);
sf := TGPStringFormat.Create();
sf.SetAlignment(StringAlignmentCenter);
sf.SetLineAlignment(StringAlignmentCenter);
g.DrawString(Format('%d%%', [percent]), -, f, MakeRect(0.0, 0.0, Self.Width, Self.Height), sf, sb);
end; var
g: TGPGraphics;
p: TGPPen;
pw: Integer;
r: TGPRectF;
angle: Single;
begin
g := TGPGraphics.Create(ACanvas.Handle);
p := TGPPen.Create(ColorRefToARGB(FForeColor), FPenWidth);
try
pw := FPenWidth;
if not FFullCover then
pw := pw + ;
r := MakeRect(pw / , pw / , Self.Width - pw - , Self.Height - pw - ); g.SetSmoothingMode(SmoothingModeHighQuality);
angle := (FCurValue - FMinValue) * / FMaxValue;
g.DrawArc(p, r, -, angle); //画百分比
if FShowText then
DrawPercent(g);
finally
p.Free;
g.Free;
end;
end; procedure TCircleProgress.Paint;
var
bmp: TBitmap;
begin
inherited; bmp := TBitmap.Create;
try
bmp.Height := Height;
bmp.Width := Width;
DrawBackground(bmp.Canvas);
DrawProgress(bmp.Canvas); Canvas.CopyMode := cmSrcCopy;
Canvas.Draw(, , bmp)
finally
bmp.Free;
end;
end; procedure TCircleProgress.ReSize;
begin
inherited; if FPenWidth > Self.Width div - then
begin
FPenWidth := Self.Width div - ;
Invalidate;
end;
end; procedure TCircleProgress.SetBackColor(const Value: TColor);
begin
if FBackColor <> Value then
begin
FBackColor := Value;
Invalidate;
end;
end; procedure TCircleProgress.SetForeColor(const Value: TColor);
begin
if FForeColor <> Value then
begin
FForeColor := Value;
Invalidate;
end;
end; procedure TCircleProgress.SetFullCover(const Value: Boolean);
begin
if FFullCover <> Value then
begin
FFullCover := Value;
Invalidate;
end;
end; procedure TCircleProgress.SetMaxValue(const Value: Integer);
begin
if FMaxValue <> Value then
begin
if Value < FMinValue then
if not (csLoading in ComponentState) then
raise EInvalidOperation.CreateFmt(SOutOfRange, [FMinValue + , MaxInt]); FMaxValue := Value;
if FCurValue > Value then FCurValue := Value;
Invalidate;
end;
end; procedure TCircleProgress.SetMinValue(const Value: Integer);
begin
if FMinValue <> Value then
begin
if Value > FMaxValue then
if not (csLoading in ComponentState) then
raise EInvalidOperation.CreateFmt(SOutOfRange, [-MaxInt, FMaxValue - ]); FMinValue := Value;
if FCurValue < Value then FCurValue := Value;
Invalidate;
end;
end; procedure TCircleProgress.SetPenWidth(const Value: Integer);
begin
if FPenWidth <> Value then
begin
FPenWidth := Value;
if FPenWidth < then
FPenWidth :=
else if FPenWidth > Self.Width div - then
FPenWidth := Self.Width div - ;
Invalidate;
end;
end; procedure TCircleProgress.SetProgress(const Value: Integer);
begin
iF FCurValue <> Value then
begin
FCurValue := Value;
if FCurValue < FMinValue then
FCurValue := FMinValue
else if FCurValue > FMaxValue then
FCurValue := FMaxValue; Invalidate;
end;
end; procedure TCircleProgress.SetShowText(const Value: Boolean);
begin
if FShowText <> Value then
begin
FShowText := Value;
Invalidate;
end;
end; end.

定时器调用:

procedure TfrmMain.tmrStartTimer(Sender: TObject);
begin
cp.Progress := cp.Progress + ;
if cp.Progress >= cp.MaxValue then
tmrStart.Enabled := False;
end;

效果:

源码:

https://files.cnblogs.com/files/crwy/cp.rar

Delphi: 圆形进度(环形进度)的更多相关文章

  1. 图解CSS3制作圆环形进度条的实例教程

    圆环形进度条制作的基本思想还是画出基本的弧线图形,然后CSS3中我们可以控制其旋转来串联基本图形,制造出部分消失的效果,下面就来带大家学习图解CSS3制作圆环形进度条的实例教程 首先,当有人说你能不能 ...

  2. iOS 开发技巧-制作环形进度条

    有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现. 先看一下这篇博客,博客地址:ht ...

  3. iOS-swift环形进度指示器+图片加载动画

    demo.gif 如图,这个动画的是如何做的呢? 分析: 1.环形进度指示器,根据下载进度来更新它 2.扩展环,向内向外扩展这个环,中间扩展的时候,去掉这个遮盖 一.环形进度指示器 1.自定义View ...

  4. iOS一分钟学会环形进度条

    有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现.先看一下这篇博客,博客地址:htt ...

  5. canvas绘制环形进度条

    <!DOCTYPE html> <html > <head> <meta http-equiv="content-type" conten ...

  6. 【CSS】环形进度条

    效果图 原理剖析 1.先完成这样一个半圆(这个很简单吧) 2.overflow: hidden; 3.在中间定位一个白色的圆形做遮挡 4.完成另一半 5.使用animate配合时间完成衔接 源码 &l ...

  7. canvas环形进度条

    <style> canvas { border: 1px solid red; margin: 100px; }</style> <canvas id="rin ...

  8. canvas实现半圆环形进度条

    html部分 <canvas id="canvas" width="150" height="150"> <p>抱歉 ...

  9. 仿MIUI音量变化环形进度条实现

    Android中使用环形进度条的业务场景事实上蛮多的,比方下载文件的时候使用环形进度条.会给用户眼前一亮的感觉:再比方我大爱的MIUI系统,它的音量进度条就是使用环形进度条,尽显小米"为发烧 ...

随机推荐

  1. day04-完整性约束

    完整性约束 关键字: not null 与 default unique primary auto_increment foreign key 1.介绍 约束条件与数据类型的宽度一样,都是可选参数作用 ...

  2. Spark读取配置(转)

    转自:https://github.com/keepsimplefocus/spark-sourcecodes-analysis/blob/master/markdowns/Spark%E8%AF%B ...

  3. Unable to locate Spring NamespaceHandler for XML schema namespace

    1. 问题 本文将讨论Spring中最常见的配置问题 —— Spring的一个命名空间的名称空间处理程序没有找到. 大多数情况下,是由于一个特定的Spring的jar没有配置在classpath下,让 ...

  4. Delphi编写Shell扩展

    用delphi创建一个外壳扩展(Shell Extension)程序的基本步骤如下: (1) 创建一个 ActiveX Library 工程,命名为“CloudUpload“(2) 创建一个新的自动化 ...

  5. Java swing 项目写成bat文件

    java  -Dfile.encoding=GBK -Xms512m -Xmx512m -cp .;.\lib\*  com.bozhirui.show.TableIn 以上为bat 文件的所有内容 ...

  6. 开发JSP自定义标签

    互联网上有很多种自定义标签,今天学的这种非常简单哟 1 编写一个普通类在类中定义一个经常使用得到的 函数 如public String toUpper(String str){ ...... } 2 ...

  7. subline 相关

    ctrl + ` 输入命令: import urllib.request,os; pf = 'Package Control.sublime-package'; ipp = sublime.insta ...

  8. JS计算滚动条的宽度

    1.此方法检验成功 function getScrollbarWidth() { var oP = document.createElement('p'), styles = { width: '10 ...

  9. macbook pro。已经连接上wifi,但是,不能上网的问题

    有天,macbook pro关机后,再打开就上不了网了,后面网上看了,说是安装了 lantern出问题,我一想,有次关机lantern是被我强制关掉的.所以再次打开lantern就可以 上网了,然后正 ...

  10. 定时删除文件夹"$1"下最后修改时间大于当前时间"$2"天的文件

    shell 脚本: #!/bin/bash now=`date "+%Y-%m-%d_%H:%M:%S"`      #获取当前时间 echo "当前时间: " ...