You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
10 KiB
328 lines
10 KiB
using Tiobon.Core.OPS.Tool.OPS.Tool.Helper;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using ThreadingTimer = System.Threading.Timer;
|
|
using UITimer = System.Windows.Forms.Timer;
|
|
|
|
namespace Loading
|
|
{
|
|
public partial class FrmLoading : Form
|
|
{
|
|
/// <summary>
|
|
/// 构造器
|
|
/// </summary>
|
|
public FrmLoading()
|
|
{
|
|
InitializeComponent();
|
|
SetStyle(
|
|
ControlStyles.AllPaintingInWmPaint |
|
|
ControlStyles.UserPaint |
|
|
ControlStyles.OptimizedDoubleBuffer,
|
|
true);
|
|
//初始化绘图timer
|
|
_tmrGraphics = new UITimer { Interval = 1 };
|
|
//Invalidate()强制重绘,绘图操作在OnPaint中实现
|
|
_tmrGraphics.Tick += (sender, e) => PnlImage.Invalidate(false);
|
|
_dotSize = PnlImage.Width / 10f;
|
|
//初始化"点"
|
|
_dots = new LoadingDot[7];
|
|
Color = Color.White;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 构造器
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
public FrmLoading(string message)
|
|
{
|
|
InitializeComponent();
|
|
//双缓冲,禁擦背景
|
|
SetStyle(
|
|
ControlStyles.AllPaintingInWmPaint |
|
|
ControlStyles.UserPaint |
|
|
ControlStyles.OptimizedDoubleBuffer,
|
|
true);
|
|
//初始化绘图timer
|
|
_tmrGraphics = new UITimer { Interval = 1 };
|
|
//Invalidate()强制重绘,绘图操作在OnPaint中实现
|
|
_tmrGraphics.Tick += (sender, e) => PnlImage.Invalidate(false);
|
|
_dotSize = PnlImage.Width / 10f;
|
|
//初始化"点"
|
|
_dots = new LoadingDot[7];
|
|
Color = Color.FromArgb(255, 73, 77);
|
|
Message = message;
|
|
Const.write_task_log(message);
|
|
}
|
|
|
|
private void FrmLoading_Load(object sender, EventArgs e)
|
|
{
|
|
LblMessage.ForeColor = Color;
|
|
if (Owner != null)
|
|
{
|
|
StartPosition = FormStartPosition.Manual;
|
|
Location = new Point(Owner.Left, Owner.Top);
|
|
Width = Owner.Width;
|
|
Height = Owner.Height;
|
|
}
|
|
else
|
|
{
|
|
var screenRect = Screen.PrimaryScreen.WorkingArea;
|
|
Location = new Point((screenRect.Width - Width) / 2, (screenRect.Height - Height) / 2);
|
|
}
|
|
Start();
|
|
}
|
|
|
|
private void FrmLoading_Shown(object sender, EventArgs e)
|
|
{
|
|
if (_workAction != null)
|
|
{
|
|
try
|
|
{
|
|
_workThread = new Thread(ExecWorkAction);
|
|
_workThread.IsBackground = true;
|
|
_workThread.Start();
|
|
}
|
|
catch (Exception ex )
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
|
|
#region 属性
|
|
|
|
[Description("消息")]
|
|
public string Message
|
|
{
|
|
get { return LblMessage.Text; }
|
|
set { LblMessage.Text = value; }
|
|
}
|
|
|
|
[Browsable(false), Description("圆心")]
|
|
public PointF CircleCenter => new PointF(PnlImage.Width / 2f, PnlImage.Height / 2f);
|
|
|
|
[Browsable(false), Description("半径")]
|
|
public float CircleRadius => PnlImage.Width / 2f - _dotSize;
|
|
|
|
[Browsable(true), Category("Appearance"), Description("设置\"点\"的前景色")]
|
|
public Color Color { get; set; }
|
|
|
|
#endregion 属性
|
|
|
|
#region 字段
|
|
|
|
[Description("工作是否完成")]
|
|
public bool IsWorkCompleted;
|
|
|
|
[Description("工作动作")]
|
|
private ParameterizedThreadStart _workAction;
|
|
|
|
[Description("工作动作参数")]
|
|
private object _workActionArg;
|
|
|
|
[Description("工作线程")]
|
|
private Thread _workThread;
|
|
|
|
[Description("工作异常")]
|
|
public Exception WorkException { get; private set; }
|
|
|
|
[Description("点数组")] private readonly LoadingDot[] _dots;
|
|
|
|
[Description("UITimer")] private readonly UITimer _tmrGraphics;
|
|
|
|
[Description("ThreadingTimer")] private ThreadingTimer _tmrAction;
|
|
|
|
[Description("点大小")] private float _dotSize;
|
|
|
|
[Description("是否活动")] private bool _isActived;
|
|
|
|
[Description("是否绘制:用于状态重置时挂起与恢复绘图")] private bool _isDrawing = true;
|
|
|
|
[Description("Timer计数:用于延迟启动每个点 ")] private int _timerCount;
|
|
|
|
#endregion 字段
|
|
|
|
#region 常量
|
|
|
|
[Description("动作间隔(Timer)")] private const int ActionInterval = 30;
|
|
|
|
[Description("计数基数:用于计算每个点启动延迟:index * timerCountRadix")] private const int TimerCountRadix = 45;
|
|
|
|
#endregion 常量
|
|
|
|
#region 方法
|
|
|
|
/// <summary>
|
|
/// 设置工作动作
|
|
/// </summary>
|
|
/// <param name="workAction"></param>
|
|
/// <param name="arg"></param>
|
|
public void SetWorkAction(ParameterizedThreadStart workAction, object arg)
|
|
{
|
|
_workAction = workAction;
|
|
_workActionArg = arg;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行工作动作
|
|
/// </summary>
|
|
private void ExecWorkAction()
|
|
{
|
|
try
|
|
{
|
|
var workTask = new Task(arg =>
|
|
{
|
|
_workAction(arg);
|
|
}, _workActionArg);
|
|
workTask.Start();
|
|
Task.WaitAll(workTask);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
WorkException = exception;
|
|
}
|
|
finally
|
|
{
|
|
IsWorkCompleted = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查是否重置
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool CheckToReset()
|
|
{
|
|
return _dots.Count(d => d.Opacity > 0) == 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化点元素
|
|
/// </summary>
|
|
private void CreateLoadingDots()
|
|
{
|
|
for (var i = 0; i < _dots.Length; ++i)
|
|
_dots[i] = new LoadingDot(CircleCenter, CircleRadius);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开始
|
|
/// </summary>
|
|
public void Start()
|
|
{
|
|
CreateLoadingDots();
|
|
_timerCount = 0;
|
|
foreach (var dot in _dots)
|
|
{
|
|
dot.Reset();
|
|
}
|
|
_tmrGraphics.Start();
|
|
//初始化动作timer
|
|
_tmrAction = new ThreadingTimer(
|
|
state =>
|
|
{
|
|
try
|
|
{
|
|
//动画动作
|
|
for (var i = 0; i < _dots.Length; i++)
|
|
{
|
|
if (_timerCount++ > i * TimerCountRadix)
|
|
{
|
|
_dots[i].LoadingDotAction();
|
|
}
|
|
}
|
|
//是否重置
|
|
if (CheckToReset())
|
|
{
|
|
//重置前暂停绘图
|
|
_isDrawing = false;
|
|
_timerCount = 0;
|
|
foreach (var dot in _dots)
|
|
{
|
|
dot.Reset();
|
|
}
|
|
//恢复绘图
|
|
_isDrawing = true;
|
|
}
|
|
_tmrAction.Change(ActionInterval, Timeout.Infinite);
|
|
}
|
|
catch { }
|
|
},
|
|
null, ActionInterval, Timeout.Infinite);
|
|
_isActived = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
_tmrGraphics.Stop();
|
|
_tmrAction.Dispose();
|
|
_isActived = false;
|
|
}
|
|
|
|
#endregion 方法
|
|
|
|
#region 重写
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
if (IsWorkCompleted)
|
|
{
|
|
Stop();
|
|
Close();
|
|
}
|
|
}
|
|
|
|
private void PnlImage_Paint(object sender, PaintEventArgs e)
|
|
{
|
|
if (_isActived && _isDrawing)
|
|
{
|
|
//抗锯齿
|
|
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
|
|
using (var bitmap = new Bitmap(200, 200))
|
|
{
|
|
//缓冲绘制
|
|
using (var bufferGraphics = Graphics.FromImage(bitmap))
|
|
{
|
|
//抗锯齿
|
|
bufferGraphics.SmoothingMode = SmoothingMode.HighQuality;
|
|
foreach (var dot in _dots)
|
|
{
|
|
var rectangleF = new RectangleF(
|
|
new PointF(dot.Location.X - _dotSize / 2, dot.Location.Y - _dotSize / 2),
|
|
new SizeF(_dotSize, _dotSize));
|
|
bufferGraphics.FillEllipse(new SolidBrush(Color.FromArgb(dot.Opacity, Color)),
|
|
rectangleF);
|
|
}
|
|
}
|
|
//贴图
|
|
e.Graphics.DrawImage(bitmap, new PointF(0, 0));
|
|
} //bmp disposed
|
|
}
|
|
base.OnPaint(e);
|
|
}
|
|
|
|
private void PnlImage_Resize(object sender, EventArgs e)
|
|
{
|
|
PnlImage.Height = PnlImage.Width;
|
|
_dotSize = PnlImage.Width / 12f;
|
|
OnResize(e);
|
|
}
|
|
|
|
|
|
#endregion 重写
|
|
|
|
private void Timer1_Tick(object sender, EventArgs e)
|
|
{
|
|
LblMessage.Text = Const.read_task_log();
|
|
}
|
|
}
|
|
} |