// COPYRIGHT (C) Tom. ALL RIGHTS RESERVED.
// THE AntdUI PROJECT IS AN WINFORM LIBRARY LICENSED UNDER THE Apache-2.0 License.
// LICENSED UNDER THE Apache License, VERSION 2.0 (THE "License")
// YOU MAY NOT USE THIS FILE EXCEPT IN COMPLIANCE WITH THE License.
// YOU MAY OBTAIN A COPY OF THE LICENSE AT
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
// DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
// LIMITATIONS UNDER THE License.
// GITEE: https://gitee.com/antdui/AntdUI
// GITHUB: https://github.com/AntdUI/AntdUI
// CSDN: https://blog.csdn.net/v_132
// QQ: 17379620
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace AntdUI
{
///
/// Progress 进度条
///
/// 展示操作的当前进度。
[Description("Progress 进度条")]
[ToolboxItem(true)]
[DefaultProperty("Value")]
public class Progress : IControl
{
#region 属性
Color? fore;
///
/// 文字颜色
///
[Description("文字颜色"), Category("外观"), DefaultValue(null)]
[Editor(typeof(Design.ColorEditor), typeof(UITypeEditor))]
public new Color? ForeColor
{
get => fore;
set
{
if (fore == value) fore = value;
fore = value;
Invalidate();
}
}
#region 背景
Color? back;
///
/// 背景颜色
///
[Description("背景颜色"), Category("外观"), DefaultValue(null)]
[Editor(typeof(Design.ColorEditor), typeof(UITypeEditor))]
public Color? Back
{
get => back;
set
{
if (back == value) return;
back = value;
Invalidate();
}
}
Color? fill;
///
/// 进度条颜色
///
[Description("进度条颜色"), Category("外观"), DefaultValue(null)]
[Editor(typeof(Design.ColorEditor), typeof(UITypeEditor))]
public Color? Fill
{
get => fill;
set
{
if (fill == value) return;
fill = value;
Invalidate();
}
}
#endregion
int radius = 0;
///
/// 圆角
///
[Description("圆角"), Category("外观"), DefaultValue(0)]
public int Radius
{
get => radius;
set
{
if (radius == value) return;
radius = value;
Invalidate();
}
}
TShapeProgress shape = TShapeProgress.Round;
///
/// 形状
///
[Description("形状"), Category("外观"), DefaultValue(TShapeProgress.Round)]
public TShapeProgress Shape
{
get => shape;
set
{
if (shape == value) return;
shape = value;
Invalidate();
}
}
#region 显示文本
string? text = null;
///
/// 文本
///
[Description("文本"), Category("外观"), DefaultValue(null)]
public override string? Text
{
get => text;
set
{
if (text == value) return;
text = value;
if (useSystemText) Invalidate();
OnTextChanged(EventArgs.Empty);
}
}
string? textUnit = "%";
///
/// 单位文本
///
[Description("单位文本"), Category("外观"), DefaultValue("%")]
public string? TextUnit
{
get => textUnit;
set
{
if (textUnit == value) return;
textUnit = value;
Invalidate();
}
}
bool useSystemText = false;
///
/// 使用系统文本
///
[Description("使用系统文本"), Category("外观"), DefaultValue(false)]
public bool UseSystemText
{
get => useSystemText;
set
{
if (useSystemText == value) return;
useSystemText = value;
Invalidate();
}
}
///
/// 显示进度文本小数点位数
///
[Description("显示进度文本小数点位数"), Category("外观"), DefaultValue(0)]
public int ShowTextDot { get; set; } = 0;
#endregion
TType state = TType.None;
///
/// 状态
///
[Description("状态"), Category("外观"), DefaultValue(TType.None)]
public TType State
{
get => state;
set
{
if (state == value) return;
state = value;
Invalidate();
if (showInTaskbar) ShowTaskbar();
}
}
float iconratio = .7F;
///
/// 图标比例
///
[Description("图标比例"), Category("外观"), DefaultValue(.7F)]
public float IconRatio
{
get => iconratio;
set
{
if (iconratio == value) return;
iconratio = value;
Invalidate();
}
}
float valueratio = .4F;
///
/// 进度条比例
///
[Description("进度条比例"), Category("外观"), DefaultValue(.4F)]
public float ValueRatio
{
get => valueratio;
set
{
if (valueratio == value) return;
valueratio = value;
Invalidate();
}
}
#region 进度条
float _value = 0F;
float _value_show = 0F;
///
/// 进度条
///
[Description("进度条 0F-1F"), Category("数据"), DefaultValue(0F)]
public float Value
{
get => _value;
set
{
if (_value == value) return;
if (value < 0) value = 0;
else if (value > 1) value = 1;
_value = value;
ThreadValue?.Dispose();
ThreadValue = null;
if (Config.Animation && IsHandleCreated && Animation > 0)
{
var t = AntdUI.Animation.TotalFrames(10, Animation);
if (_value > _value_show)
{
float s = _value_show, v = Math.Abs(_value - s);
ThreadValue = new ITask((i) =>
{
_value_show = s + AntdUI.Animation.Animate(i, t, v, AnimationType.Ball);
Invalidate();
return true;
}, 10, t, () =>
{
_value_show = _value;
Invalidate();
});
}
else
{
float s = _value_show, v = Math.Abs(_value_show - _value);
ThreadValue = new ITask((i) =>
{
_value_show = s - AntdUI.Animation.Animate(i, t, v, AnimationType.Ball);
Invalidate();
return true;
}, 10, t, () =>
{
_value_show = _value;
Invalidate();
});
}
}
else
{
_value_show = _value;
Invalidate();
}
if (showInTaskbar) ShowTaskbar();
}
}
///
/// Value格式化时发生
///
[Description("Value格式化时发生"), Category("行为")]
public event ProgressFormatEventHandler? ValueFormatChanged;
#endregion
bool loading = false;
float AnimationLoadingValue = 0F;
///
/// 加载状态
///
[Description("加载状态"), Category("外观"), DefaultValue(false)]
public bool Loading
{
get => loading;
set
{
if (loading == value) return;
loading = value;
ThreadLoading?.Dispose();
if (showInTaskbar) ShowTaskbar(!loading);
if (loading)
{
ThreadLoading = new ITask(this, () =>
{
AnimationLoadingValue = AnimationLoadingValue.Calculate(0.01F);
if (AnimationLoadingValue > 1)
{
AnimationLoadingValue = 0;
Invalidate();
Thread.Sleep(1000);
}
Invalidate();
return loading;
}, 10, () =>
{
Invalidate();
});
}
else Invalidate();
}
}
///
/// 动画铺满
///
[Description("动画铺满"), Category("外观"), DefaultValue(false)]
public bool LoadingFull { get; set; } = false;
///
/// 动画时长
///
[Description("动画时长"), Category("外观"), DefaultValue(200)]
public int Animation { get; set; } = 200;
#region 步骤
int steps = 3;
///
/// 进度条总共步数
///
[Description("进度条总共步数"), Category("外观"), DefaultValue(3)]
public int Steps
{
get => steps;
set
{
if (steps == value) return;
steps = value;
if (shape == TShapeProgress.Steps) Invalidate();
}
}
int stepSize = 14;
///
/// 步数大小
///
[Description("步数大小"), Category("外观"), DefaultValue(14)]
public int StepSize
{
get => stepSize;
set
{
if (stepSize == value) return;
stepSize = value;
if (shape == TShapeProgress.Steps) Invalidate();
}
}
int stepGap = 2;
///
/// 步数间隔
///
[Description("步数间隔"), Category("外观"), DefaultValue(2)]
public int StepGap
{
get => stepGap;
set
{
if (stepGap == value) return;
stepGap = value;
if (shape == TShapeProgress.Steps) Invalidate();
}
}
#endregion
#region 动画
protected override void Dispose(bool disposing)
{
ThreadLoading?.Dispose();
ThreadValue?.Dispose();
base.Dispose(disposing);
}
ITask? ThreadLoading = null;
ITask? ThreadValue = null;
#endregion
#region 任务栏
ContainerControl? ownerForm;
///
/// 窗口对象
///
[Description("窗口对象"), Category("任务栏"), DefaultValue(null)]
public ContainerControl? ContainerControl
{
get => ownerForm;
set => ownerForm = value;
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (ownerForm == null) ownerForm = Parent.FindPARENT();
ITask.Run(() =>
{
Thread.Sleep(100);
canTaskbar = true;
if (showInTaskbar) ShowTaskbar();
});
}
bool showInTaskbar = false;
///
/// 任务栏中显示进度
///
[Description("任务栏中显示进度"), Category("外观"), DefaultValue(false)]
public bool ShowInTaskbar
{
get => showInTaskbar;
set
{
if (showInTaskbar == value) return;
showInTaskbar = value;
if (canTaskbar)
{
if (showInTaskbar) ShowTaskbar();
else if (ownerForm != null) TaskbarProgressState(ownerForm, ThumbnailProgressState.NoProgress);
}
}
}
bool canTaskbar = false;
void ShowTaskbar(bool sl = false)
{
if (canTaskbar)
{
if (ownerForm == null) return;
if (state == TType.None)
{
if (_value == 0 && loading)
{
TaskbarProgressValue(ownerForm, 0);
TaskbarProgressState(ownerForm, ThumbnailProgressState.Indeterminate);
}
else
{
if (sl && old_state == ThumbnailProgressState.Indeterminate) TaskbarProgressState(ownerForm, ThumbnailProgressState.NoProgress);
TaskbarProgressState(ownerForm, ThumbnailProgressState.Normal);
TaskbarProgressValue(ownerForm, (ulong)(_value * 100));
}
}
else
{
switch (state)
{
case TType.Error:
TaskbarProgressState(ownerForm, ThumbnailProgressState.Error);
break;
case TType.Warn:
TaskbarProgressState(ownerForm, ThumbnailProgressState.Paused);
break;
default:
TaskbarProgressState(ownerForm, ThumbnailProgressState.Normal);
break;
}
TaskbarProgressValue(ownerForm, (ulong)(_value * 100));
}
}
}
void TaskbarProgressState(ContainerControl hwnd, ThumbnailProgressState state)
{
if (old_state == state) return;
old_state = state;
if (InvokeRequired)
{
Invoke(new Action(() =>
{
Windows7Taskbar.SetProgressState(hwnd.Handle, state);
}));
return;
}
Windows7Taskbar.SetProgressState(hwnd.Handle, state);
}
ulong old_value = 0;
ThumbnailProgressState old_state = ThumbnailProgressState.NoProgress;
void TaskbarProgressValue(ContainerControl hwnd, ulong value)
{
if (old_value == value) return;
old_value = value;
if (InvokeRequired)
{
Invoke(new Action(() =>
{
Windows7Taskbar.SetProgressValue(hwnd.Handle, value);
}));
return;
}
Windows7Taskbar.SetProgressValue(hwnd.Handle, value);
}
#endregion
#endregion
#region 渲染
readonly StringFormat s_c = Helper.SF_ALL(), s_r = Helper.SF_ALL(lr: StringAlignment.Far), s_l = Helper.SF_ALL(lr: StringAlignment.Near);
protected override void OnPaint(PaintEventArgs e)
{
var rect_t = ClientRectangle;
var rect = rect_t.PaddingRect(Padding);
var g = e.Graphics.High();
Color color;
switch (state)
{
case TType.Success:
color = fill ?? Style.Db.Success;
break;
case TType.Info:
color = fill ?? Style.Db.Info;
break;
case TType.Warn:
color = fill ?? Style.Db.Warning;
break;
case TType.Error:
color = fill ?? Style.Db.Error;
break;
case TType.None:
default:
color = fill ?? Style.Db.Primary;
break;
}
switch (shape)
{
case TShapeProgress.Circle:
PaintShapeCircle(g, rect, color);
break;
case TShapeProgress.Mini:
PaintShapeMini(g, rect, color);
break;
case TShapeProgress.Steps:
PaintShapeSteps(g, rect_t, rect, color);
break;
case TShapeProgress.Round:
PaintShapeRound(g, rect_t, rect, color, true);
break;
case TShapeProgress.Default:
default:
PaintShapeRound(g, rect_t, rect, color, false);
break;
}
this.PaintBadge(g);
base.OnPaint(e);
}
void PaintShapeMini(Graphics g, Rectangle rect, Color color)
{
var _back = back ?? Color.FromArgb(40, color);
var font_size = g.MeasureString("100" + textUnit, Font).Size();
rect.IconRectL(font_size.Height, out var icon_rect, out var text_rect, iconratio);
if (icon_rect.Width == 0 || icon_rect.Height == 0) return;
using (var brush = new SolidBrush(fore ?? Style.Db.Text))
{
string textShow = ValueFormatChanged?.Invoke(this, new FloatEventArgs(_value_show)) ?? (useSystemText ? text ?? "" : (_value_show * 100F).ToString("F" + ShowTextDot) + textUnit);
g.DrawStr(textShow, Font, brush, new Rectangle(text_rect.X + 8, text_rect.Y, text_rect.Width - 8, text_rect.Height), s_l);
}
int w = radius == 0 ? (int)Math.Round(icon_rect.Width * .2F) : (int)(radius * Config.Dpi);
using (var brush = new Pen(_back, w))
{
g.DrawEllipse(brush, icon_rect);
}
#region 进度条
int max = 0;
if (_value_show > 0)
{
max = (int)Math.Round(360 * _value_show);
using (var brush = new Pen(color, w))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, icon_rect, -90, max);
}
}
if (loading && AnimationLoadingValue > 0)
{
if (_value_show > 0)
{
float alpha = 60 * (1F - AnimationLoadingValue);
using (var brush = new Pen(Helper.ToColor(alpha, Style.Db.BgBase), w))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, icon_rect, -90, (int)(max * AnimationLoadingValue));
}
}
else if (LoadingFull)
{
max = 360;
float alpha = 80 * (1F - AnimationLoadingValue);
using (var brush = new Pen(Helper.ToColor(alpha, Style.Db.BgBase), w))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, icon_rect, -90, (int)(max * AnimationLoadingValue));
}
}
}
#endregion
}
void PaintShapeSteps(Graphics g, Rectangle rect_t, Rectangle rect, Color color)
{
var _back = back ?? Style.Db.FillSecondary;
var font_size = g.MeasureString("100" + textUnit, Font).Size();
int pro_gap = (int)(stepGap * Config.Dpi), pro_h = (int)(font_size.Height * valueratio);
float pro_w = (int)(stepSize * Config.Dpi), has_x = 0;
int pro_y = rect.Y + (rect.Height - pro_h) / 2;
var prog = steps * _value_show;
using (var brush = new SolidBrush(_back))
using (var brush_fill = new SolidBrush(color))
{
if (pro_w <= 0)
{
float w = rect.Width;
if (state == TType.None)
{
string textShow = ValueFormatChanged?.Invoke(this, new FloatEventArgs(_value_show)) ?? (useSystemText ? text ?? "" : (_value_show * 100F).ToString("F" + ShowTextDot) + textUnit);
w -= g.MeasureString(textShow, Font).Size().Width + pro_h / 2;
}
else
{
int ico_size = (int)(font_size.Height * (iconratio + 0.1F));
w -= ico_size + pro_h * 2 + pro_h / 2;
}
pro_w = (w - pro_gap * (steps - 1F)) / steps;
}
if (pro_w > 0)
{
for (int i = 0; i < steps; i++)
{
g.FillRectangle(prog > i ? brush_fill : brush, new RectangleF(rect.X + has_x, pro_y, pro_w, pro_h));
has_x += pro_w + pro_gap;
}
}
}
if (state == TType.None)
{
int has_x2 = (int)Math.Ceiling(has_x + pro_h / 2);
using (var brush = new SolidBrush(fore ?? Style.Db.Text))
{
string textShow = ValueFormatChanged?.Invoke(this, new FloatEventArgs(_value_show)) ?? (useSystemText ? text ?? "" : (_value_show * 100F).ToString("F" + ShowTextDot) + textUnit);
g.DrawStr(textShow, Font, brush, new Rectangle(rect.X + has_x2, rect.Y, rect.Width - has_x2, rect.Height), s_l);
}
}
else
{
int has_x2 = (int)Math.Ceiling(has_x);
int ico_size = (int)(font_size.Height * (iconratio + 0.1F)), size_font_w = pro_h + ico_size;
g.PaintIcons(state, new Rectangle((rect.X + has_x2 + size_font_w) - ico_size, rect_t.Y + (rect_t.Height - ico_size) / 2, ico_size, ico_size));
}
}
void PaintShapeRound(Graphics g, Rectangle rect_t, Rectangle rect, Color color, bool round)
{
var _back = back ?? Style.Db.FillSecondary;
float _radius = radius * Config.Dpi;
if (round) _radius = rect.Height;
if (state == TType.None)
{
string? showtmp, textShow;
if (ValueFormatChanged == null)
{
if (useSystemText) showtmp = textShow = text;
else
{
string basetext = (_value_show * 100F).ToString("F" + ShowTextDot);
var chars = new char[basetext.Length];
chars[0] = basetext[0];
for (int i = 1; i < basetext.Length; i++)
{
if (basetext[i] == '.') chars[i] = '.';
else chars[i] = '0';
}
showtmp = string.Join("", chars) + textUnit;
textShow = basetext + textUnit;
}
}
else showtmp = textShow = ValueFormatChanged(this, new FloatEventArgs(_value_show));
if (showtmp == null && textShow == null)
{
var sizef = g.MeasureString(Config.NullText, Font).Size();
int pro_h = (int)(sizef.Height * valueratio);
rect.Y = rect.Y + (rect.Height - pro_h) / 2;
rect.Height = pro_h;
PaintProgress(g, _radius, rect, _back, color);
}
else
{
var sizef = g.MeasureString(showtmp, Font).Size();
int pro_h = (int)(sizef.Height * valueratio), size_font_w = (int)Math.Ceiling(sizef.Width + sizef.Height * .2F);
var rect_rext = new Rectangle(rect.Right - size_font_w, rect_t.Y, size_font_w, rect_t.Height);
rect.Y = rect.Y + (rect.Height - pro_h) / 2;
rect.Height = pro_h;
rect.Width -= size_font_w;
PaintProgress(g, _radius, rect, _back, color);
using (var brush = new SolidBrush(fore ?? Style.Db.Text))
{
g.DrawStr(textShow, Font, brush, rect_rext, s_r);
}
}
}
else
{
string showtext = (_value_show * 100F).ToString("F" + ShowTextDot) + textUnit;
var sizef = g.MeasureString(showtext, Font).Size();
int pro_h = (int)(sizef.Height * valueratio), ico_size = (int)(sizef.Height * (iconratio + 0.1F));
int size_font_w = pro_h + ico_size;
var rect_rext = new Rectangle(rect.Right - size_font_w, rect_t.Y, size_font_w, rect_t.Height);
rect.Y = rect.Y + (rect.Height - pro_h) / 2;
rect.Height = pro_h;
rect.Width -= size_font_w;
PaintProgress(g, _radius, rect, _back, color);
g.PaintIcons(state, new Rectangle(rect_rext.Right - ico_size, rect_rext.Y + (rect_rext.Height - ico_size) / 2, ico_size, ico_size));
}
}
void PaintShapeCircle(Graphics g, Rectangle rect, Color color)
{
var _back = back ?? Style.Db.FillSecondary;
int prog_size;
if (rect.Width == rect.Height) prog_size = rect.Width;
else if (rect.Width > rect.Height) prog_size = rect.Height;
else prog_size = rect.Width;
int w = radius == 0 ? (int)Math.Round(prog_size * .04F) : (int)(radius * Config.Dpi);
prog_size -= w;
var rect_prog = new Rectangle(rect.X + (rect.Width - prog_size) / 2, rect.Y + (rect.Height - prog_size) / 2, prog_size, prog_size);
using (var brush = new Pen(_back, w))
{
g.DrawEllipse(brush, rect_prog);
}
#region 进度条
int max = 0;
if (_value_show > 0)
{
max = (int)Math.Round(360 * _value_show);
using (var brush = new Pen(color, w))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect_prog, -90, max);
}
}
if (loading && AnimationLoadingValue > 0)
{
if (_value_show > 0)
{
float alpha = 60 * (1F - AnimationLoadingValue);
using (var brush = new Pen(Helper.ToColor(alpha, Style.Db.BgBase), w))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect_prog, -90, (int)(max * AnimationLoadingValue));
}
}
else if (LoadingFull)
{
max = 360;
float alpha = 80 * (1F - AnimationLoadingValue);
using (var brush = new Pen(Helper.ToColor(alpha, Style.Db.BgBase), w))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect_prog, -90, (int)(max * AnimationLoadingValue));
}
}
}
#endregion
if (_value_show > 0)
{
if (state == TType.None)
{
using (var brush = new SolidBrush(fore ?? Style.Db.Text))
{
string textShow = ValueFormatChanged?.Invoke(this, new FloatEventArgs(_value_show)) ?? (useSystemText ? text ?? "" : (_value_show * 100F).ToString("F" + ShowTextDot) + textUnit);
g.DrawStr(textShow, Font, brush, rect, s_c);
}
}
else
{
int size = (int)(rect_prog.Width * .26F);
g.PaintIconGhosts(state, new Rectangle(rect.X + (rect.Width - size) / 2, rect.Y + (rect.Height - size) / 2, size, size), color);
}
}
else
{
using (var brush = new SolidBrush(fore ?? Style.Db.Text))
{
string textShow = ValueFormatChanged?.Invoke(this, new FloatEventArgs(_value_show)) ?? (useSystemText ? text ?? "" : (_value_show * 100F).ToString("F" + ShowTextDot) + textUnit);
g.DrawStr(textShow, Font, brush, rect, s_c);
}
}
}
void PaintProgress(Graphics g, float radius, Rectangle rect, Color back, Color color)
{
using (var path = rect.RoundPath(radius))
{
using (var brush = new SolidBrush(back))
{
g.FillPath(brush, path);
}
bool handloading = true;
if (_value_show > 0)
{
var _w = rect.Width * _value_show;
if (_w > radius)
{
using (var path_prog = new RectangleF(rect.X, rect.Y, _w, rect.Height).RoundPath(radius))
{
using (var brush = new SolidBrush(color))
{
g.FillPath(brush, path_prog);
}
}
if (loading && AnimationLoadingValue > 0)
{
handloading = false;
var alpha = 60 * (1F - AnimationLoadingValue);
using (var brush = new SolidBrush(Helper.ToColor(alpha, Style.Db.BgBase)))
{
using (var path_prog = new RectangleF(rect.X, rect.Y, _w * AnimationLoadingValue, rect.Height).RoundPath(radius))
{
g.FillPath(brush, path_prog);
}
}
}
}
else
{
using (var bmp = new Bitmap(rect.Width, rect.Height))
{
using (var g2 = Graphics.FromImage(bmp).High())
{
using (var brush = new SolidBrush(color))
{
using (var path_prog = new RectangleF(-_w, 0, _w * 2, rect.Height).RoundPath(radius))
{
g2.FillPath(brush, path_prog);
}
}
if (loading && AnimationLoadingValue > 0)
{
handloading = false;
var alpha = 60 * (1F - AnimationLoadingValue);
using (var brush = new SolidBrush(Helper.ToColor(alpha, Style.Db.BgBase)))
{
using (var path_prog = new RectangleF(-_w, 0, _w * 2 * AnimationLoadingValue, rect.Height).RoundPath(radius))
{
g2.FillPath(brush, path_prog);
}
}
}
}
using (var brush = new TextureBrush(bmp, WrapMode.Clamp))
{
brush.TranslateTransform(rect.X, rect.Y);
g.FillPath(brush, path);
}
}
}
}
if (loading && AnimationLoadingValue > 0 && handloading && LoadingFull)
{
var alpha = 80 * (1F - AnimationLoadingValue);
using (var brush = new SolidBrush(Helper.ToColor(alpha, Style.Db.BgBase)))
{
using (var path_prog = new RectangleF(rect.X, rect.Y, rect.Width * AnimationLoadingValue, rect.Height).RoundPath(radius))
{
g.FillPath(brush, path_prog);
}
}
}
}
}
#endregion
}
#region 任务栏
internal static class Windows7Taskbar
{
static ITaskbarList3? _taskbarList;
internal static ITaskbarList3 TaskbarList
{
get
{
if (_taskbarList == null)
{
_taskbarList = (ITaskbarList3)new CTaskbarList();
_taskbarList.HrInit();
}
return _taskbarList;
}
}
///
/// Sets the progress state of the specified window's
/// taskbar button.
///
/// The window handle.
/// The progress state.
public static void SetProgressState(IntPtr hwnd, ThumbnailProgressState state)
{
TaskbarList.SetProgressState(hwnd, state);
}
///
/// Sets the progress value of the specified window's
/// taskbar button.
///
/// The window handle.
/// The current value.
/// The maximum value.
public static void SetProgressValue(IntPtr hwnd, ulong current, ulong maximum)
{
TaskbarList.SetProgressValue(hwnd, current, maximum);
}
public static void SetProgressValue(IntPtr hwnd, ulong current)
{
TaskbarList.SetProgressValue(hwnd, current, 100);
}
}
///
/// 表示缩略图进度条状态。
///
internal enum ThumbnailProgressState
{
///
/// 没有进度。
///
NoProgress = 0,
///
/// 不确定的进度 (marquee)。
///
Indeterminate = 0x1,
///
/// 正常进度
///
Normal = 0x2,
///
/// 错误进度 (red).
///
Error = 0x4,
///
/// 暂停进度 (yellow).
///
Paused = 0x8
}
[Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]
[ClassInterface(ClassInterfaceType.None)]
[ComImport]
internal class CTaskbarList { }
[ComImport]
[Guid("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITaskbarList3
{
[PreserveSig]
void HrInit();
[PreserveSig]
void AddTab(IntPtr hwnd);
[PreserveSig]
void DeleteTab(IntPtr hwnd);
[PreserveSig]
void ActivateTab(IntPtr hwnd);
[PreserveSig]
void SetActiveAlt(IntPtr hwnd);
// ITaskbarList2
[PreserveSig]
void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
// ITaskbarList3
void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
void SetProgressState(IntPtr hwnd, ThumbnailProgressState tbpFlags);
}
#endregion
}