起源:

重回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. Leetcode 题解 Trapping Rain Water

    题目链接:https://leetcode.com/problems/trapping-rain-water/description/ 思路: 1.先找到最左侧第一个高度不为0的柱子i. 2.从i+1 ...

  2. ubuntu 安装 oracle sql developer

    安装java-jdk 这一部分教程很多,可按照网上教程进行安装 安装sqldeveloper 下载 sqldeveloper Linux RPM http://www.oracle.com/techn ...

  3. es6 初级之let

    1.在es6 中,定义变量使用 let. 1.1 var定义变量: <!DOCTYPE html> <html lang="en"> <head> ...

  4. javascript:解决两个小数相乘出现无限小数

    两个小数相乘,会出现无限小数:先把小数乘以10或100或1000(小数点后有多少位就乘以多少),再相乘,最后再除以10或100或1000

  5. LISTVIEW显示JPEG缩略图

    http://www.ctsys.cn/files/SHOW_FILES.ASPX?ID=22 许多的JPEG图片浏览器(如由我设计的<JPEG浏览缩放器>),都可以将JPEG缩略图放置到 ...

  6. 4.Java的流程控制.md

    目录 1. break语句 2.continue 3.foreach语句 4.可变参数: 1. break语句 Java的break语句,正常情况下,break和c++一样,但是Java可以设置一个标 ...

  7. python 基础回顾 一

    Python 基础回顾 可变类型:list ,dict 不可变类型:string,tuple,numbers tuple是不可变的,但是它包含的list dict是可变的. set 集合内部是唯一的 ...

  8. UI简单工作

     UI用户界面 需求——效果图——风格设计——高保证效果——html 网页的宽度=屏幕的宽度-纵向滚动条的宽度 企业网站一般是1280 根据百度流量研究所 目前我们的网页注主要是1024和1200   ...

  9. (转)Python新手写出漂亮的爬虫代码2——从json获取信息

    https://blog.csdn.net/weixin_36604953/article/details/78592943 Python新手写出漂亮的爬虫代码2——从json获取信息好久没有写关于爬 ...

  10. Oracle Oracle数据库 迁移到 SQL Server上

    原地址:https://blog.csdn.net/LongtengGensSupreme/article/details/81355181