// 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 }