浏览代码

新增旋转按钮控件、新增系统阻止待机和息屏的API

yuzhengyang 8 年之前
父节点
当前提交
2d9def5b5e
共有 32 个文件被更改,包括 1524 次插入61 次删除
  1. 二进制
      Fork.Net/.vs/Fork.Net/v15/Server/sqlite3/storage.ide
  2. 二进制
      Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide
  3. 1 0
      Fork.Net/Azylee.Utils/Azylee.Core/Azylee.Core.csproj
  4. 17 0
      Fork.Net/Azylee.Utils/Azylee.Core/DataUtils/StringUtils/StringTool.cs
  5. 7 1
      Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/Log.cs
  6. 10 0
      Fork.Net/Azylee.Utils/Azylee.Core/Readme.cs
  7. 71 0
      Fork.Net/Azylee.Utils/Azylee.Core/WindowsUtils/APIUtils/SystemSleepAPI.cs
  8. 9 0
      Fork.Net/Azylee.Utils/Azylee.WinformSkin/Azylee.WinformSkin.csproj
  9. 49 0
      Fork.Net/Azylee.Utils/Azylee.WinformSkin/ButtonUI/RotateImageButton.Designer.cs
  10. 225 0
      Fork.Net/Azylee.Utils/Azylee.WinformSkin/ButtonUI/RotateImageButton.cs
  11. 123 0
      Fork.Net/Azylee.Utils/Azylee.WinformSkin/ButtonUI/RotateImageButton.resx
  12. 3 1
      Fork.Net/Azylee.Utils/Azylee.WinformSkin/FormUI/NoTitle/NoTitleForm.cs
  13. 77 56
      Fork.Net/Azylee.Utils/Azylee.WinformSkin/UserWidgets/ClockWidgets/SimpleClockControl.cs
  14. 11 0
      Fork.Net/Fork.Net.sln
  15. 125 0
      Fork.Net/Test/Test.SystemSleep/Form1.Designer.cs
  16. 45 0
      Fork.Net/Test/Test.SystemSleep/Form1.cs
  17. 123 0
      Fork.Net/Test/Test.SystemSleep/Form1.resx
  18. 21 0
      Fork.Net/Test/Test.SystemSleep/Program.cs
  19. 36 0
      Fork.Net/Test/Test.SystemSleep/Properties/AssemblyInfo.cs
  20. 71 0
      Fork.Net/Test/Test.SystemSleep/Properties/Resources.Designer.cs
  21. 117 0
      Fork.Net/Test/Test.SystemSleep/Properties/Resources.resx
  22. 30 0
      Fork.Net/Test/Test.SystemSleep/Properties/Settings.Designer.cs
  23. 7 0
      Fork.Net/Test/Test.SystemSleep/Properties/Settings.settings
  24. 83 0
      Fork.Net/Test/Test.SystemSleep/Test.SystemSleep.csproj
  25. 二进制
      Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon.png
  26. 二进制
      Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon_back.png
  27. 二进制
      Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon_back_down.png
  28. 二进制
      Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon_fore.png
  29. 73 2
      Fork.Net/Test/Y.Test/Views/MainForm.Designer.cs
  30. 4 1
      Fork.Net/Test/Y.Test/Views/MainForm.cs
  31. 182 0
      Fork.Net/Test/Y.Test/Views/MainForm.resx
  32. 4 0
      Fork.Net/Test/Y.Test/Y.Test.csproj

二进制
Fork.Net/.vs/Fork.Net/v15/Server/sqlite3/storage.ide


二进制
Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide


+ 1 - 0
Fork.Net/Azylee.Utils/Azylee.Core/Azylee.Core.csproj

@@ -83,6 +83,7 @@
     <Compile Include="TaskUtils\TaskSupport.cs" />
     <Compile Include="VersionUtils\VersionTool.cs" />
     <Compile Include="WindowsUtils\APIUtils\PermissionAPI.cs" />
+    <Compile Include="WindowsUtils\APIUtils\SystemSleepAPI.cs" />
     <Compile Include="WindowsUtils\APIUtils\WindowsAPI.cs" />
     <Compile Include="WindowsUtils\InfoUtils\ComputerInfoTool.cs" />
     <Compile Include="WindowsUtils\InfoUtils\NetcardInfoTool.cs" />

+ 17 - 0
Fork.Net/Azylee.Utils/Azylee.Core/DataUtils/StringUtils/StringTool.cs

@@ -6,6 +6,7 @@
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
 using Azylee.Core.DataUtils.CollectionUtils;
+using System;
 using System.Text.RegularExpressions;
 
 namespace Azylee.Core.DataUtils.StringUtils
@@ -81,5 +82,21 @@ namespace Azylee.Core.DataUtils.StringUtils
                 return false;
             }
         }
+        /// <summary>
+        /// 使用指定字符替换字符串中换行符
+        /// </summary>
+        /// <param name="s"></param>
+        /// <param name="sign"></param>
+        /// <returns></returns>
+        public static string ReplaceNewLine(string s, string sign = " , ")
+        {
+            try
+            {
+                return s.Replace("\r\n", sign).
+                Replace("\n\r", sign).
+                Replace(Environment.NewLine, sign);
+            }
+            catch { return s; }
+        }
     }
 }

+ 7 - 1
Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/Log.cs

@@ -16,6 +16,7 @@
 //R.Log.e("this is e 错误");
 
 using Azylee.Core.DataUtils.CollectionUtils;
+using Azylee.Core.DataUtils.StringUtils;
 using Azylee.Core.IOUtils.DirUtils;
 using Azylee.Core.IOUtils.TxtUtils;
 using System;
@@ -164,7 +165,12 @@ namespace Azylee.Core.LogUtils
                     //创建日志目录
                     DirTool.Create(logPath);
                     //写出日志
-                    TxtTool.Append(file, string.Format(LOG_FORMAT, log.CreateTime.ToString(TIME_FORMAT), log.Type.ToString(), log.Message));
+                    TxtTool.Append(
+                        file,
+                        string.Format(LOG_FORMAT,
+                            log.CreateTime.ToString(TIME_FORMAT),
+                            log.Type.ToString(),
+                            StringTool.ReplaceNewLine(log.Message)));
                 }
             }
         }

+ 10 - 0
Fork.Net/Azylee.Utils/Azylee.Core/Readme.cs

@@ -12,3 +12,13 @@
 //      desc:       工具描述
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
+
+
+//************************************************************************
+//      https://github.com/yuzhengyang
+//      author:     yuzhengyang
+//      date:       2017.3.29 - 2017.6.10
+//      desc:       工具描述
+//      Copyright (c) yuzhengyang. All rights reserved.
+//      Quote:
+//************************************************************************

+ 71 - 0
Fork.Net/Azylee.Utils/Azylee.Core/WindowsUtils/APIUtils/SystemSleepAPI.cs

@@ -0,0 +1,71 @@
+//************************************************************************
+//      https://github.com/yuzhengyang
+//      author:     yuzhengyang
+//      date:       2018.3.9 - 2018.3.9
+//      desc:       工具描述
+//      Copyright (c) yuzhengyang. All rights reserved.
+//      Quote:https://www.cnblogs.com/TianFang/archive/2012/10/12/2721883.html
+//************************************************************************
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Azylee.Core.WindowsUtils.APIUtils
+{
+    public class SystemSleepAPI
+    {
+        //定义API函数
+        [DllImport("kernel32.dll")]
+        static extern uint SetThreadExecutionState(ExecutionFlag flags);
+
+        [Flags]
+        enum ExecutionFlag : uint
+        {
+            System = 0x00000001,
+            Display = 0x00000002,
+            Continus = 0x80000000,
+        }
+
+        /// <summary>
+        /// 阻止系统休眠
+        /// </summary>
+        /// <param name="screen">阻止息屏</param>
+        public static void PreventSleep(bool screen = false)
+        {
+            try
+            {
+                if (screen)
+                    SetThreadExecutionState(ExecutionFlag.System | ExecutionFlag.Display | ExecutionFlag.Continus);
+                else
+                    SetThreadExecutionState(ExecutionFlag.System | ExecutionFlag.Continus);
+            }
+            catch { }
+        }
+
+        /// <summary>
+        /// 恢复系统休眠和息屏
+        /// </summary>
+        public static void ResotreSleep()
+        {
+            try { SetThreadExecutionState(ExecutionFlag.Continus); } catch { }
+        }
+
+        /// <summary>
+        /// 重置系统休眠计时器
+        /// </summary>
+        /// <param name="screen">阻止息屏</param>
+        public static void ResetSleepTimer(bool screen = false)
+        {
+            try
+            {
+                if (screen)
+                    SetThreadExecutionState(ExecutionFlag.System | ExecutionFlag.Display);
+                else
+                    SetThreadExecutionState(ExecutionFlag.System);
+            }
+            catch { }
+        }
+    }
+}

+ 9 - 0
Fork.Net/Azylee.Utils/Azylee.WinformSkin/Azylee.WinformSkin.csproj

@@ -49,6 +49,12 @@
     <Compile Include="ButtonUI\ImageButton.Designer.cs">
       <DependentUpon>ImageButton.cs</DependentUpon>
     </Compile>
+    <Compile Include="ButtonUI\RotateImageButton.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="ButtonUI\RotateImageButton.Designer.cs">
+      <DependentUpon>RotateImageButton.cs</DependentUpon>
+    </Compile>
     <Compile Include="FormUI\CustomTitle\BigIconForm.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -117,6 +123,9 @@
     <EmbeddedResource Include="ButtonUI\ImageButton.resx">
       <DependentUpon>ImageButton.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="ButtonUI\RotateImageButton.resx">
+      <DependentUpon>RotateImageButton.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="FormUI\CustomTitle\BigIconForm.resx">
       <DependentUpon>BigIconForm.cs</DependentUpon>
     </EmbeddedResource>

+ 49 - 0
Fork.Net/Azylee.Utils/Azylee.WinformSkin/ButtonUI/RotateImageButton.Designer.cs

@@ -0,0 +1,49 @@
+namespace Azylee.WinformSkin.ButtonUI
+{
+    partial class RotateImageButton
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // RotateImageButton
+            // 
+            this.LoadCompleted += new System.ComponentModel.AsyncCompletedEventHandler(this.RotateImageButton_LoadCompleted);
+            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ImageButton_MouseDown);
+            this.MouseEnter += new System.EventHandler(this.ImageButton_MouseEnter);
+            this.MouseLeave += new System.EventHandler(this.ImageButton_MouseLeave);
+            this.MouseHover += new System.EventHandler(this.ImageButton_MouseHover);
+            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ImageButton_MouseUp);
+            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+    }
+}

+ 225 - 0
Fork.Net/Azylee.Utils/Azylee.WinformSkin/ButtonUI/RotateImageButton.cs

@@ -0,0 +1,225 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+
+namespace Azylee.WinformSkin.ButtonUI
+{
+    public partial class RotateImageButton : PictureBox
+    {
+        #region 属性
+        #region 背景
+        private Image _BackImageDefault = null;
+        [Category("自定义属性")]
+        [Description("正常显示背景")]
+        public Image BackImageDefault
+        {
+            get { return _BackImageDefault; }
+            set
+            {
+                _BackImageDefault = value;
+                BackgroundImage = _BackImageDefault;
+            }
+        }
+
+        private Image _BackImageHover = null;
+        [Category("自定义属性")]
+        [Description("鼠标悬停背景")]
+        public Image BackImageHover
+        {
+            get { return _BackImageHover; }
+            set { _BackImageHover = value; }
+        }
+
+        private Image _BackImageDown = null;
+        [Category("自定义属性")]
+        [Description("鼠标按下背景")]
+        public Image BackImageDown
+        {
+            get { return _BackImageDown; }
+            set { _BackImageDown = value; }
+        }
+        #endregion
+        #region 前景
+        private Image _ForeImageDefault = null;
+        [Category("自定义属性")]
+        [Description("正常显示前景")]
+        public Image ForeImageDefault
+        {
+            get { return _ForeImageDefault; }
+            set
+            {
+                _ForeImageDefault = value;
+                Image = _ForeImageDefault;
+            }
+        }
+        #endregion
+        #endregion
+
+        Graphics Graph = null;
+        Timer TMPainter = new Timer();
+        const int Interval = 50;
+        int AnimaAngle = 0;
+        const int AngleStep = 5;
+        Bitmap Bmp = null;
+        Graphics BmpGraph = null;
+        bool IsInit = false;
+
+        public RotateImageButton()
+        {
+            InitializeComponent();
+            //采用双缓冲技术的控件必需的设置
+            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+            SetStyle(ControlStyles.UserPaint, true);
+
+            if (!DesignMode)
+            {
+                Graph = CreateGraphics();
+                Graph.SmoothingMode = SmoothingMode.AntiAlias;
+
+                TMPainter.Interval = Interval;
+                TMPainter.Tick += TMPainter_Tick;
+            }
+        }
+        private void RotateImageButton_LoadCompleted(object sender, AsyncCompletedEventArgs e)
+        {
+
+        }
+
+        #region 事件
+        /// <summary>
+        /// 鼠标进入
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ImageButton_MouseEnter(object sender, EventArgs e)
+        {
+            if (BackImageHover != null)
+                BackgroundImage = BackImageHover;
+            else
+                Stop();
+        }
+        /// <summary>
+        /// 鼠标悬停
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ImageButton_MouseHover(object sender, EventArgs e)
+        {
+            if (BackImageHover != null)
+                BackgroundImage = BackImageHover;
+            else
+                Stop();
+
+            Start();
+        }
+        /// <summary>
+        /// 鼠标移出
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ImageButton_MouseLeave(object sender, EventArgs e)
+        {
+            Stop();
+        }
+        /// <summary>
+        /// 鼠标按下
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ImageButton_MouseDown(object sender, MouseEventArgs e)
+        {
+            Stop();
+
+            if (BackImageDown != null) BackgroundImage = BackImageDown;
+        }
+        /// <summary>
+        /// 鼠标抬起
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ImageButton_MouseUp(object sender, MouseEventArgs e)
+        {
+            if (BackImageHover != null)
+                BackgroundImage = BackImageHover;
+            else
+                Stop();
+        }
+        private void TMPainter_Tick(object sender, EventArgs e)
+        {
+            Draw();
+        }
+        #endregion  
+
+
+        /// <summary>
+        /// 开始动画
+        /// </summary>
+        private void Start()
+        {
+            if (ForeImageDefault != null && !TMPainter.Enabled)
+            {
+                //之前设置为0,导致开始执行到18次时会抽搐一下子
+                AnimaAngle = 360;
+                TMPainter.Enabled = true;
+            }
+        }
+        /// <summary>
+        /// 停止并恢复到默认状态
+        /// </summary>
+        private void Stop()
+        {
+            TMPainter.Enabled = false;
+            Image = ForeImageDefault;
+            BackgroundImage = BackImageDefault;
+        }
+        private void Init()
+        {
+            try
+            {
+                if (!IsInit)
+                {
+                    Bmp = new Bitmap(Width, Height);
+                    BmpGraph = Graphics.FromImage(Bmp);
+                    BmpGraph.SmoothingMode = SmoothingMode.AntiAlias;
+                    IsInit = true;
+                }
+            }
+            catch { }
+        }
+        private void Draw()
+        {
+            try
+            {
+                Init();
+                if (Graph != null && Bmp != null && BmpGraph != null)
+                {
+                    BmpGraph.Clear(Color.Transparent);
+                    //绘制
+                    if (ForeImageDefault != null)
+                    {
+                        BmpGraph.ResetTransform();//恢复默认状态
+                        BmpGraph.TranslateTransform(Width / 2, Height / 2);//设置原点
+                        BmpGraph.RotateTransform(AnimaAngle += AngleStep);//以水平线为x轴,从垂直上方开始旋转,每次旋转6度。
+                        BmpGraph.DrawImage(ForeImageDefault, -(Width / 2), -(Height / 2), Width, Height);
+                    }
+                    Image = Bmp;
+                }
+            }
+            catch { }
+        }
+        ~RotateImageButton()
+        {
+            BmpGraph.Dispose();
+            Bmp.Dispose();
+            Graph.Dispose();
+        }
+    }
+}

+ 123 - 0
Fork.Net/Azylee.Utils/Azylee.WinformSkin/ButtonUI/RotateImageButton.resx

@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+</root>

+ 3 - 1
Fork.Net/Azylee.Utils/Azylee.WinformSkin/FormUI/NoTitle/NoTitleForm.cs

@@ -153,8 +153,10 @@ namespace Azylee.WinformSkin.FormUI.NoTitle
         {
             get
             {
+                const int WS_MINIMIZEBOX = 0x00020000;  // Winuser.h中定义  
                 CreateParams cp = base.CreateParams;
-                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED  
+                cp.Style = cp.Style | WS_MINIMIZEBOX;   // 允许最小化操作
+                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED(任务栏点击最大化最小化)
                 return cp;
             }
         }

+ 77 - 56
Fork.Net/Azylee.Utils/Azylee.WinformSkin/UserWidgets/ClockWidgets/SimpleClockControl.cs

@@ -8,6 +8,7 @@ using System.Text;
 using System.Windows.Forms;
 using System.Drawing.Drawing2D;
 using Azylee.WinformSkin.Properties;
+using System.Drawing.Imaging;
 
 namespace Azylee.WinformSkin.UserWidgets.ClockWidgets
 {
@@ -40,11 +41,24 @@ namespace Azylee.WinformSkin.UserWidgets.ClockWidgets
             get { return _HourHandImage; }
             set { _HourHandImage = value; }
         }
+
+        private Image _ClockBackImage = null;
+        [Category("时钟样式")]
+        [Description("表盘")]
+        public Image ClockBackImage
+        {
+            get { return _ClockBackImage; }
+            set
+            {
+                _ClockBackImage = value;
+                BackgroundImage = _ClockBackImage;
+            }
+        }
         #endregion
-        Graphics Graph = null;
         Bitmap Bmp = null;
-        Graphics BmpGraph = null;
+        Graphics Graph = null;
         DateTime Time = DateTime.Now;
+        double TimeShift = 0;
         public SimpleClockControl()
         {
             InitializeComponent();
@@ -53,101 +67,108 @@ namespace Azylee.WinformSkin.UserWidgets.ClockWidgets
             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
             SetStyle(ControlStyles.UserPaint, true);
         }
-
         private void SimpleClockControl_Load(object sender, EventArgs e)
         {
         }
-        public void Start()
-        {
-            Graph = CreateGraphics();
-            Graph.SmoothingMode = SmoothingMode.AntiAlias;
-            Bmp = new Bitmap(Width, Height);
-            BmpGraph = Graphics.FromImage(Bmp);
-            BmpGraph.SmoothingMode = SmoothingMode.AntiAlias;
-            TMPainter.Interval = 1 * 1000;
-
-            if (SecondHandImage == null)
-            {
-                TMPainter.Interval = 60 * 1000;
-                //SecondHandImage = Resources.simpleclock_simple_second_hand_1;
-            }
-            if (MinuteHandImage == null)
-            {
-                TMPainter.Interval = 60 * 60 * 1000;
-                MinuteHandImage = Resources.simpleclock_simple_minute_hand_1;
-            }
-            if (HourHandImage == null)
-            {
-                HourHandImage = Resources.simpleclock_simple_hour_hand_1;
-            }
 
+        #region 对外提供方法
+        /// <summary>
+        /// 启动时钟刷新
+        /// </summary>
+        /// <param name="secondInterval">刷新间隔时间()</param>
+        /// <param name="timeShift">时间偏移(小时)</param>
+        public void Start(int secondInterval = 1, double timeShift = 0)
+        {
+            Init(timeShift);//初始化数据
             Draw();//第一次绘制
-            TMPainter.Enabled = true;
+            TMPainter.Interval = (secondInterval >= 1 ? secondInterval : 1) * 1000;//设置刷新间隔
+            TMPainter.Enabled = true;//启动计时器任务
         }
+        /// <summary>
+        /// 强制重绘控件
+        /// </summary>
         public void ReDraw()
         {
             Draw();
         }
+        #endregion
+
         private void TMPainter_Tick(object sender, EventArgs e)
         {
             Draw();
         }
+        private void Init(double timeShift)
+        {
+            try
+            {
+                Bmp = new Bitmap(Width, Height);
+                Graph = Graphics.FromImage(Bmp);
+                Graph.SmoothingMode = SmoothingMode.AntiAlias;
+                TimeShift = timeShift;
 
+                if (SecondHandImage == null)
+                {
+                    //TMPainter.Interval = 60 * 1000;
+                    //SecondHandImage = Resources.simpleclock_simple_second_hand_1;
+                }
+                if (MinuteHandImage == null)
+                {
+                    //TMPainter.Interval = 60 * 60 * 1000;
+                    MinuteHandImage = Resources.simpleclock_simple_minute_hand_1;
+                }
+                if (HourHandImage == null)
+                {
+                    HourHandImage = Resources.simpleclock_simple_hour_hand_1;
+                }
+            }
+            catch { }
+        }
         private void Draw()
         {
             try
             {
-                if (Graph != null && Bmp != null && BmpGraph != null)
+                if (Bmp != null && Graph != null)
                 {
-                    Refresh();//强制重绘控件
-                    Time = DateTime.Now;
-                    BmpGraph.ResetTransform();//恢复默认状态
-                    BmpGraph.FillRectangle(new SolidBrush(BackColor), 0, 0, Width, Height);
-                    if (BackgroundImage != null) BmpGraph.DrawImage(BackgroundImage, 0, 0, Width, Height);
+                    Time = DateTime.Now.AddHours(TimeShift);
+                    Graph.ResetTransform();//恢复默认状态
+                    Graph.Clear(Color.Transparent);
+                    Graph.FillRectangle(new SolidBrush(BackColor), 0, 0, Width, Height);
+                    if (ClockBackImage != null) Graph.DrawImage(ClockBackImage, 0, 0, Width, Height);
 
                     //绘制时针
                     if (HourHandImage != null)
                     {
-                        BmpGraph.ResetTransform();//恢复默认状态
-                        BmpGraph.TranslateTransform(Width / 2, Height / 2);//设置原点
-                        BmpGraph.RotateTransform(Time.Hour * 30 + Time.Minute * 1 / 2);
-                        BmpGraph.DrawImage(HourHandImage, -(Width / 2), -(Height / 2), Width, Height);
+                        Graph.ResetTransform();//恢复默认状态
+                        Graph.TranslateTransform(Width / 2, Height / 2);//设置原点
+                        Graph.RotateTransform(Time.Hour * 30 + Time.Minute * 1 / 2);
+                        Graph.DrawImage(HourHandImage, -(Width / 2), -(Height / 2), Width, Height);
                     }
                     //绘制分针
                     if (MinuteHandImage != null)
                     {
-                        BmpGraph.ResetTransform();//恢复默认状态
-                        BmpGraph.TranslateTransform(Width / 2, Height / 2);//设置原点
-                        BmpGraph.RotateTransform(Time.Minute * 6);
-                        BmpGraph.DrawImage(MinuteHandImage, -(Width / 2), -(Height / 2), Width, Height);
+                        Graph.ResetTransform();//恢复默认状态
+                        Graph.TranslateTransform(Width / 2, Height / 2);//设置原点
+                        Graph.RotateTransform(Time.Minute * 6);
+                        Graph.DrawImage(MinuteHandImage, -(Width / 2), -(Height / 2), Width, Height);
                     }
                     //绘制秒针
                     if (SecondHandImage != null)
                     {
-                        BmpGraph.ResetTransform();//恢复默认状态
-                        BmpGraph.TranslateTransform(Width / 2, Height / 2);//设置原点
-                        BmpGraph.RotateTransform(Time.Second * 6);//以水平线为x轴,从垂直上方开始旋转,每次旋转6度。
-                        BmpGraph.DrawImage(SecondHandImage, -(Width / 2), -(Height / 2), Width, Height);
+                        Graph.ResetTransform();//恢复默认状态
+                        Graph.TranslateTransform(Width / 2, Height / 2);//设置原点
+                        Graph.RotateTransform(Time.Second * 6);//以水平线为x轴,从垂直上方开始旋转,每次旋转6度。
+                        Graph.DrawImage(SecondHandImage, -(Width / 2), -(Height / 2), Width, Height);
                     }
-                    OnPaint(new PaintEventArgs(Graph, new Rectangle(0, 0, Width, Height)));
+                    BackgroundImage = Bmp;
+                    Refresh();
                 }
             }
             catch { }
         }
-        protected override void OnPaint(PaintEventArgs e)
-        {
-            base.OnPaint(e);
-            if (!DesignMode && e != null && e.Graphics != null && Bmp != null)
-            {
-                Graphics g = e.Graphics;
-                g.DrawImage(Bmp, 0, 0, Width, Height);
-            }
-        }
         ~SimpleClockControl()
         {
             Graph.Dispose();
             Bmp.Dispose();
-            BmpGraph.Dispose();
         }
     }
 }

+ 11 - 0
Fork.Net/Fork.Net.sln

@@ -75,6 +75,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.Update", "Azylee.Uti
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.Core.Plus", "Azylee.Utils\Azylee.Core.Plus\Azylee.Core.Plus.csproj", "{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.SystemSleep", "Test\Test.SystemSleep\Test.SystemSleep.csproj", "{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -331,6 +333,14 @@ Global
 		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Release|x86.ActiveCfg = Release|Any CPU
 		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Release|x86.Build.0 = Release|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Debug|x86.Build.0 = Debug|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Release|x86.ActiveCfg = Release|Any CPU
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -366,6 +376,7 @@ Global
 		{EF587677-DC59-4C46-B1AB-92904CD3F187} = {C34A95B5-5F83-46E3-868A-56BDDA2D0B87}
 		{76F92BAE-8C9C-42AA-85E8-51F2EA8A0C91} = {C34A95B5-5F83-46E3-868A-56BDDA2D0B87}
 		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0} = {C34A95B5-5F83-46E3-868A-56BDDA2D0B87}
+		{3936BB3B-244D-4448-9B77-3A7CC0CFBE28} = {A89FC45A-A907-4487-8719-114530A62684}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {5436696D-5F55-490A-AB40-050B54BE2AB4}

+ 125 - 0
Fork.Net/Test/Test.SystemSleep/Form1.Designer.cs

@@ -0,0 +1,125 @@
+namespace Test.SystemSleep
+{
+    partial class Form1
+    {
+        /// <summary>
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows 窗体设计器生成的代码
+
+        /// <summary>
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.button1 = new System.Windows.Forms.Button();
+            this.button2 = new System.Windows.Forms.Button();
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.timer1 = new System.Windows.Forms.Timer(this.components);
+            this.SuspendLayout();
+            // 
+            // button1
+            // 
+            this.button1.Location = new System.Drawing.Point(35, 131);
+            this.button1.Name = "button1";
+            this.button1.Size = new System.Drawing.Size(75, 23);
+            this.button1.TabIndex = 0;
+            this.button1.Text = "阻止";
+            this.button1.UseVisualStyleBackColor = true;
+            this.button1.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // button2
+            // 
+            this.button2.Location = new System.Drawing.Point(163, 131);
+            this.button2.Name = "button2";
+            this.button2.Size = new System.Drawing.Size(75, 23);
+            this.button2.TabIndex = 1;
+            this.button2.Text = "恢复";
+            this.button2.UseVisualStyleBackColor = true;
+            this.button2.Click += new System.EventHandler(this.button2_Click);
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(33, 33);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(125, 12);
+            this.label1.TabIndex = 2;
+            this.label1.Text = "阻止计算机休眠、待机";
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(33, 82);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(29, 12);
+            this.label2.TabIndex = 3;
+            this.label2.Text = "默认";
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(12, 231);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(71, 12);
+            this.label3.TabIndex = 4;
+            this.label3.Text = "计时:0:0:0";
+            // 
+            // timer1
+            // 
+            this.timer1.Enabled = true;
+            this.timer1.Interval = 1000;
+            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(276, 252);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Controls.Add(this.button2);
+            this.Controls.Add(this.button1);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "Form1";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+            this.Text = "Form1";
+            this.Load += new System.EventHandler(this.Form1_Load);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.Button button2;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Timer timer1;
+    }
+}
+

+ 45 - 0
Fork.Net/Test/Test.SystemSleep/Form1.cs

@@ -0,0 +1,45 @@
+using Azylee.Core.DataUtils.DateTimeUtils;
+using Azylee.Core.WindowsUtils.APIUtils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Test.SystemSleep
+{
+    public partial class Form1 : Form
+    {
+        int SleepTime = 0;
+        public Form1()
+        {
+            InitializeComponent();
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            SystemSleepAPI.PreventSleep(true);
+            label2.Text = "已阻止";
+        }
+
+        private void button2_Click(object sender, EventArgs e)
+        {
+            SystemSleepAPI.ResotreSleep();
+            label2.Text = "已恢复";
+        }
+
+        private void timer1_Tick(object sender, EventArgs e)
+        {
+            var fmt = DateTimeTool.ToHMS(SleepTime++ * 1000);
+            label3.Text = $"计时:{fmt.Item1}:{fmt.Item2}:{fmt.Item3}";
+        }
+    }
+}

+ 123 - 0
Fork.Net/Test/Test.SystemSleep/Form1.resx

@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>

+ 21 - 0
Fork.Net/Test/Test.SystemSleep/Program.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Test.SystemSleep
+{
+    static class Program
+    {
+        /// <summary>
+        /// 应用程序的主入口点。
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new Form1());
+        }
+    }
+}

+ 36 - 0
Fork.Net/Test/Test.SystemSleep/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("Test.SystemSleep")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Test.SystemSleep")]
+[assembly: AssemblyCopyright("Copyright ©  2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("3936bb3b-244d-4448-9b77-3a7cc0cfbe28")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
Fork.Net/Test/Test.SystemSleep/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Test.SystemSleep.Properties
+{
+
+
+    /// <summary>
+    ///   强类型资源类,用于查找本地化字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   返回此类使用的缓存 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Test.SystemSleep.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   覆盖当前线程的 CurrentUICulture 属性
+        ///   使用此强类型的资源类的资源查找。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
Fork.Net/Test/Test.SystemSleep/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 30 - 0
Fork.Net/Test/Test.SystemSleep/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Test.SystemSleep.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
Fork.Net/Test/Test.SystemSleep/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 83 - 0
Fork.Net/Test/Test.SystemSleep/Test.SystemSleep.csproj

@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{3936BB3B-244D-4448-9B77-3A7CC0CFBE28}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Test.SystemSleep</RootNamespace>
+    <AssemblyName>Test.SystemSleep</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Form1.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Form1.Designer.cs">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Form1.resx">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Azylee.Utils\Azylee.Core\Azylee.Core.csproj">
+      <Project>{88dc61fa-95f0-41b7-9d7d-ab0f3cbd169c}</Project>
+      <Name>Azylee.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

二进制
Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon.png


二进制
Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon_back.png


二进制
Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon_back_down.png


二进制
Fork.Net/Test/Y.Test/Images/RoteImgBtn/function_update_icon_fore.png


+ 73 - 2
Fork.Net/Test/Y.Test/Views/MainForm.Designer.cs

@@ -28,6 +28,7 @@
         /// </summary>
         private void InitializeComponent()
         {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
             this.ChineseCalendarForm = new System.Windows.Forms.Button();
             this.TestComputerInfoForm = new System.Windows.Forms.Button();
             this.TestUpdateForm = new System.Windows.Forms.Button();
@@ -38,7 +39,12 @@
             this.BTCheckYUtils = new System.Windows.Forms.Button();
             this.TestCrossForm = new System.Windows.Forms.Button();
             this.button1 = new System.Windows.Forms.Button();
+            this.simpleClockControl4 = new Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl();
+            this.rotateImageButton1 = new Azylee.WinformSkin.ButtonUI.RotateImageButton();
+            this.simpleClockControl3 = new Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl();
+            this.simpleClockControl2 = new Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl();
             this.simpleClockControl1 = new Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl();
+            ((System.ComponentModel.ISupportInitialize)(this.rotateImageButton1)).BeginInit();
             this.SuspendLayout();
             // 
             // ChineseCalendarForm
@@ -141,11 +147,67 @@
             this.button1.UseVisualStyleBackColor = true;
             this.button1.Click += new System.EventHandler(this.button1_Click);
             // 
+            // simpleClockControl4
+            // 
+            this.simpleClockControl4.BackColor = System.Drawing.Color.Transparent;
+            this.simpleClockControl4.BackgroundImage = global::Y.Test.Properties.Resources.Rainbow;
+            this.simpleClockControl4.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+            this.simpleClockControl4.ClockBackImage = global::Y.Test.Properties.Resources.Rainbow;
+            this.simpleClockControl4.HourHandImage = null;
+            this.simpleClockControl4.Location = new System.Drawing.Point(435, 285);
+            this.simpleClockControl4.MinuteHandImage = null;
+            this.simpleClockControl4.Name = "simpleClockControl4";
+            this.simpleClockControl4.SecondHandImage = global::Y.Test.Properties.Resources.temp_01;
+            this.simpleClockControl4.Size = new System.Drawing.Size(150, 150);
+            this.simpleClockControl4.TabIndex = 15;
+            // 
+            // rotateImageButton1
+            // 
+            this.rotateImageButton1.BackColor = System.Drawing.Color.Transparent;
+            this.rotateImageButton1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("rotateImageButton1.BackgroundImage")));
+            this.rotateImageButton1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+            this.rotateImageButton1.BackImageDefault = ((System.Drawing.Image)(resources.GetObject("rotateImageButton1.BackImageDefault")));
+            this.rotateImageButton1.BackImageDown = ((System.Drawing.Image)(resources.GetObject("rotateImageButton1.BackImageDown")));
+            this.rotateImageButton1.BackImageHover = null;
+            this.rotateImageButton1.ForeImageDefault = global::Y.Test.Properties.Resources.temp_01;
+            this.rotateImageButton1.Image = global::Y.Test.Properties.Resources.temp_01;
+            this.rotateImageButton1.Location = new System.Drawing.Point(267, 285);
+            this.rotateImageButton1.Name = "rotateImageButton1";
+            this.rotateImageButton1.Size = new System.Drawing.Size(64, 64);
+            this.rotateImageButton1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+            this.rotateImageButton1.TabIndex = 14;
+            this.rotateImageButton1.TabStop = false;
+            // 
+            // simpleClockControl3
+            // 
+            this.simpleClockControl3.BackColor = System.Drawing.Color.GreenYellow;
+            this.simpleClockControl3.ClockBackImage = null;
+            this.simpleClockControl3.HourHandImage = null;
+            this.simpleClockControl3.Location = new System.Drawing.Point(334, 145);
+            this.simpleClockControl3.MinuteHandImage = null;
+            this.simpleClockControl3.Name = "simpleClockControl3";
+            this.simpleClockControl3.SecondHandImage = null;
+            this.simpleClockControl3.Size = new System.Drawing.Size(64, 64);
+            this.simpleClockControl3.TabIndex = 12;
+            // 
+            // simpleClockControl2
+            // 
+            this.simpleClockControl2.BackColor = System.Drawing.Color.GreenYellow;
+            this.simpleClockControl2.ClockBackImage = null;
+            this.simpleClockControl2.HourHandImage = null;
+            this.simpleClockControl2.Location = new System.Drawing.Point(423, 58);
+            this.simpleClockControl2.MinuteHandImage = null;
+            this.simpleClockControl2.Name = "simpleClockControl2";
+            this.simpleClockControl2.SecondHandImage = null;
+            this.simpleClockControl2.Size = new System.Drawing.Size(64, 64);
+            this.simpleClockControl2.TabIndex = 11;
+            // 
             // simpleClockControl1
             // 
             this.simpleClockControl1.BackColor = System.Drawing.Color.GreenYellow;
+            this.simpleClockControl1.ClockBackImage = null;
             this.simpleClockControl1.HourHandImage = null;
-            this.simpleClockControl1.Location = new System.Drawing.Point(405, 175);
+            this.simpleClockControl1.Location = new System.Drawing.Point(334, 58);
             this.simpleClockControl1.MinuteHandImage = null;
             this.simpleClockControl1.Name = "simpleClockControl1";
             this.simpleClockControl1.SecondHandImage = null;
@@ -156,7 +218,11 @@
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(564, 427);
+            this.ClientSize = new System.Drawing.Size(609, 470);
+            this.Controls.Add(this.simpleClockControl4);
+            this.Controls.Add(this.rotateImageButton1);
+            this.Controls.Add(this.simpleClockControl3);
+            this.Controls.Add(this.simpleClockControl2);
             this.Controls.Add(this.simpleClockControl1);
             this.Controls.Add(this.button1);
             this.Controls.Add(this.TestCrossForm);
@@ -172,6 +238,7 @@
             this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
             this.Text = "MainForm";
             this.Load += new System.EventHandler(this.MainForm_Load);
+            ((System.ComponentModel.ISupportInitialize)(this.rotateImageButton1)).EndInit();
             this.ResumeLayout(false);
 
         }
@@ -189,5 +256,9 @@
         private System.Windows.Forms.Button TestCrossForm;
         private System.Windows.Forms.Button button1;
         private Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl simpleClockControl1;
+        private Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl simpleClockControl2;
+        private Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl simpleClockControl3;
+        private Azylee.WinformSkin.ButtonUI.RotateImageButton rotateImageButton1;
+        private Azylee.WinformSkin.UserWidgets.ClockWidgets.SimpleClockControl simpleClockControl4;
     }
 }

+ 4 - 1
Fork.Net/Test/Y.Test/Views/MainForm.cs

@@ -20,7 +20,10 @@ namespace Y.Test.Views
         }
         private void MainForm_Load(object sender, EventArgs e)
         {
-            simpleClockControl1.Start();
+            simpleClockControl1.Start(timeShift: 0);
+            simpleClockControl2.Start(timeShift: 4.5);
+            simpleClockControl3.Start(timeShift: -1);
+            simpleClockControl4.Start(timeShift: 10);
         }
         private void ChineseCalendarForm_Click(object sender, EventArgs e)
         {

+ 182 - 0
Fork.Net/Test/Y.Test/Views/MainForm.resx

@@ -117,4 +117,186 @@
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="rotateImageButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACH
+        DwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKOWlDQ1BQaG90b3Nob3AgSUNDIHByb2Zp
+        bGUAAEjHnZZ3VFTXFofPvXd6oc0w0hl6ky4wgPQuIB0EURhmBhjKAMMMTWyIqEBEEREBRZCggAGjoUis
+        iGIhKKhgD0gQUGIwiqioZEbWSnx5ee/l5ffHvd/aZ+9z99l7n7UuACRPHy4vBZYCIJkn4Ad6ONNXhUfQ
+        sf0ABniAAaYAMFnpqb5B7sFAJC83F3q6yAn8i94MAUj8vmXo6U+ng/9P0qxUvgAAyF/E5mxOOkvE+SJO
+        yhSkiu0zIqbGJIoZRomZL0pQxHJijlvkpZ99FtlRzOxkHlvE4pxT2clsMfeIeHuGkCNixEfEBRlcTqaI
+        b4tYM0mYzBXxW3FsMoeZDgCKJLYLOKx4EZuImMQPDnQR8XIAcKS4LzjmCxZwsgTiQ7mkpGbzuXHxArou
+        S49uam3NoHtyMpM4AoGhP5OVyOSz6S4pyalMXjYAi2f+LBlxbemiIluaWltaGpoZmX5RqP+6+Dcl7u0i
+        vQr43DOI1veH7a/8UuoAYMyKarPrD1vMfgA6tgIgd/8Pm+YhACRFfWu/8cV5aOJ5iRcIUm2MjTMzM424
+        HJaRuKC/6386/A198T0j8Xa/l4fuyollCpMEdHHdWClJKUI+PT2VyeLQDf88xP848K/zWBrIieXwOTxR
+        RKhoyri8OFG7eWyugJvCo3N5/6mJ/zDsT1qca5Eo9Z8ANcoISN2gAuTnPoCiEAESeVDc9d/75oMPBeKb
+        F6Y6sTj3nwX9+65wifiRzo37HOcSGExnCfkZi2viawnQgAAkARXIAxWgAXSBITADVsAWOAI3sAL4gWAQ
+        DtYCFogHyYAPMkEu2AwKQBHYBfaCSlAD6kEjaAEnQAc4DS6Ay+A6uAnugAdgBIyD52AGvAHzEARhITJE
+        geQhVUgLMoDMIAZkD7lBPlAgFA5FQ3EQDxJCudAWqAgqhSqhWqgR+hY6BV2ArkID0D1oFJqCfoXewwhM
+        gqmwMqwNG8MM2An2hoPhNXAcnAbnwPnwTrgCroOPwe3wBfg6fAcegZ/DswhAiAgNUUMMEQbigvghEUgs
+        wkc2IIVIOVKHtCBdSC9yCxlBppF3KAyKgqKjDFG2KE9UCIqFSkNtQBWjKlFHUe2oHtQt1ChqBvUJTUYr
+        oQ3QNmgv9Cp0HDoTXYAuRzeg29CX0HfQ4+g3GAyGhtHBWGE8MeGYBMw6TDHmAKYVcx4zgBnDzGKxWHms
+        AdYO64dlYgXYAux+7DHsOewgdhz7FkfEqeLMcO64CBwPl4crxzXhzuIGcRO4ebwUXgtvg/fDs/HZ+BJ8
+        Pb4LfwM/jp8nSBN0CHaEYEICYTOhgtBCuER4SHhFJBLVidbEACKXuIlYQTxOvEIcJb4jyZD0SS6kSJKQ
+        tJN0hHSedI/0ikwma5MdyRFkAXknuZF8kfyY/FaCImEk4SXBltgoUSXRLjEo8UISL6kl6SS5VjJHslzy
+        pOQNyWkpvJS2lIsUU2qDVJXUKalhqVlpirSptJ90snSxdJP0VelJGayMtoybDFsmX+awzEWZMQpC0aC4
+        UFiULZR6yiXKOBVD1aF6UROoRdRvqP3UGVkZ2WWyobJZslWyZ2RHaAhNm+ZFS6KV0E7QhmjvlygvcVrC
+        WbJjScuSwSVzcopyjnIcuUK5Vrk7cu/l6fJu8onyu+U75B8poBT0FQIUMhUOKlxSmFakKtoqshQLFU8o
+        3leClfSVApXWKR1W6lOaVVZR9lBOVd6vfFF5WoWm4qiSoFKmclZlSpWiaq/KVS1TPaf6jC5Ld6In0Svo
+        PfQZNSU1TzWhWq1av9q8uo56iHqeeqv6Iw2CBkMjVqNMo1tjRlNV01czV7NZ874WXouhFa+1T6tXa05b
+        RztMe5t2h/akjpyOl06OTrPOQ12yroNumm6d7m09jB5DL1HvgN5NfVjfQj9ev0r/hgFsYGnANThgMLAU
+        vdR6KW9p3dJhQ5Khk2GGYbPhqBHNyMcoz6jD6IWxpnGE8W7jXuNPJhYmSSb1Jg9MZUxXmOaZdpn+aqZv
+        xjKrMrttTjZ3N99o3mn+cpnBMs6yg8vuWlAsfC22WXRbfLS0suRbtlhOWWlaRVtVWw0zqAx/RjHjijXa
+        2tl6o/Vp63c2ljYCmxM2v9ga2ibaNtlOLtdZzllev3zMTt2OaVdrN2JPt4+2P2Q/4qDmwHSoc3jiqOHI
+        dmxwnHDSc0pwOub0wtnEme/c5jznYuOy3uW8K+Lq4Vro2u8m4xbiVun22F3dPc692X3Gw8Jjncd5T7Sn
+        t+duz2EvZS+WV6PXzAqrFetX9HiTvIO8K72f+Oj78H26fGHfFb57fB+u1FrJW9nhB/y8/Pb4PfLX8U/z
+        /z4AE+AfUBXwNNA0MDewN4gSFBXUFPQm2Dm4JPhBiG6IMKQ7VDI0MrQxdC7MNaw0bGSV8ar1q66HK4Rz
+        wzsjsBGhEQ0Rs6vdVu9dPR5pEVkQObRGZ03WmqtrFdYmrT0TJRnFjDoZjY4Oi26K/sD0Y9YxZ2O8Yqpj
+        ZlgurH2s52xHdhl7imPHKeVMxNrFlsZOxtnF7YmbineIL4+f5rpwK7kvEzwTahLmEv0SjyQuJIUltSbj
+        kqOTT/FkeIm8nhSVlKyUgVSD1ILUkTSbtL1pM3xvfkM6lL4mvVNAFf1M9Ql1hVuFoxn2GVUZbzNDM09m
+        SWfxsvqy9bN3ZE/kuOd8vQ61jrWuO1ctd3Pu6Hqn9bUboA0xG7o3amzM3zi+yWPT0c2EzYmbf8gzySvN
+        e70lbEtXvnL+pvyxrR5bmwskCvgFw9tst9VsR23nbu/fYb5j/45PhezCa0UmReVFH4pZxde+Mv2q4quF
+        nbE7+0ssSw7uwuzi7Rra7bD7aKl0aU7p2B7fPe1l9LLCstd7o/ZeLV9WXrOPsE+4b6TCp6Jzv+b+Xfs/
+        VMZX3qlyrmqtVqreUT13gH1g8KDjwZYa5ZqimveHuIfu1nrUttdp15UfxhzOOPy0PrS+92vG140NCg1F
+        DR+P8I6MHA082tNo1djYpNRU0gw3C5unjkUeu/mN6zedLYYtta201qLj4Ljw+LNvo78dOuF9ovsk42TL
+        d1rfVbdR2grbofbs9pmO+I6RzvDOgVMrTnV32Xa1fW/0/ZHTaqerzsieKTlLOJt/duFczrnZ86nnpy/E
+        XRjrjup+cHHVxds9AT39l7wvXbnsfvlir1PvuSt2V05ftbl66hrjWsd1y+vtfRZ9bT9Y/NDWb9nffsPq
+        RudN65tdA8sHzg46DF645Xrr8m2v29fvrLwzMBQydHc4cnjkLvvu5L2key/vZ9yff7DpIfph4SOpR+WP
+        lR7X/aj3Y+uI5ciZUdfRvidBTx6Mscae/5T+04fx/Kfkp+UTqhONk2aTp6fcp24+W/1s/Hnq8/npgp+l
+        f65+ofviu18cf+mbWTUz/pL/cuHX4lfyr468Xva6e9Z/9vGb5Dfzc4Vv5d8efcd41/s+7P3EfOYH7IeK
+        j3ofuz55f3q4kLyw8Bv3hPP74uYdwgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAiZJREFUeF7l2z9uE2Ec
+        hOFISOF8/G3gQqaFM9CQ+yBEQSQ4ATSEZvm9kS2ZmWmSFGTnU/Q0o531Ny6cZvdi27alxXAlMVxJDFcS
+        w5XE8PDrkFyO1+Pj+DZuxvZI8Pd5cLZXg7PahrQ1hqH8bHwd6cMfI876fPyzI22N4VnpyTiM9CF7wNnZ
+        cO8vYM/jT9hwry/g5Ug33CO2xK0xnIv5Efl+LDf4MS7TVgswF785K7d4m7ZagLn4k5QbXKWtFmAuvpZy
+        g+u01QLMxb+l3OAmbbUAoVxBd8ICpHID3QkLkMoNdCcsQCo30J2wAKncQHfCAqRyA90JC5DKDXQnLEAq
+        N9CdsACp3EB3wgKkcgPdCQuQyg10JyxAKjfQnbAAqdxAd8ICpHID3QkLkMoNdCcsQCo30J2wAKncQHfC
+        AqRyA90JC5DKDXQnLEAqN9CdsACp3EB3wgKkcgPdCQuQyg10JyxAKjfQnbAAqdxAd8ICpHID3QkLkMoN
+        dCcsQCo30J2wAKncQHfCAqRyA90JC5DKDXQnLEAqN9CdsACp3EB3wgKkcgPdCQswF//UcoE7PSLzRcoN
+        7vSQ1PKPyS3/oGTjo7JP01YLMBeDFw/SzfaILXFrDLn46N1IN9wTNtzuSVtjeCoMXjZ4P9KN9+DDeNAL
+        Eycvxt5embl9R+Bc2hpDLR7xw8h/h6vBS1N/Rvrw/4GzcCbOxhkf9tLUSmK4khiuJIYrieE6tou/ujTL
+        9sqW/UYAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="rotateImageButton1.BackImageDefault" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        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
+        9sqW/UYAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="rotateImageButton1.BackImageDown" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        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
+</value>
+  </data>
 </root>

+ 4 - 0
Fork.Net/Test/Y.Test/Y.Test.csproj

@@ -253,6 +253,10 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include="Images\IconGroup\icongroup_01.png" />
+    <Content Include="Images\RoteImgBtn\function_update_icon.png" />
+    <Content Include="Images\RoteImgBtn\function_update_icon_back.png" />
+    <Content Include="Images\RoteImgBtn\function_update_icon_back_down.png" />
+    <Content Include="Images\RoteImgBtn\function_update_icon_fore.png" />
     <Content Include="Images\Temp\temp_01.png" />
     <Content Include="Images\Temp\temp_02.png" />
     <Content Include="Images\Temp\temp_03.png" />