diff --git a/SunnyUI/Forms/UIForm2.Designer.cs b/SunnyUI/Forms/UIForm2.Designer.cs new file mode 100644 index 00000000..24cc63bd --- /dev/null +++ b/SunnyUI/Forms/UIForm2.Designer.cs @@ -0,0 +1,46 @@ +namespace Sunny.UI +{ + partial class UIForm2 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + SuspendLayout(); + // + // UIForm2 + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(800, 450); + Name = "UIForm2"; + Padding = new System.Windows.Forms.Padding(0, 35, 0, 0); + Text = "UIForm2"; + ResumeLayout(false); + } + + #endregion + } +} \ No newline at end of file diff --git a/SunnyUI/Forms/UIForm2.cs b/SunnyUI/Forms/UIForm2.cs new file mode 100644 index 00000000..d725f30d --- /dev/null +++ b/SunnyUI/Forms/UIForm2.cs @@ -0,0 +1,1004 @@ +using Sunny.UI.Win32; +using System; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace Sunny.UI +{ + public partial class UIForm2 : Form + { + public UIForm2() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true); + UpdateStyles(); + + Version = UIGlobal.Version; + fieldW = typeof(Control).GetField("_clientWidth", BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(Control).GetField("clientWidth", BindingFlags.NonPublic | BindingFlags.Instance); + fieldH = typeof(Control).GetField("_clientHeight", BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(Control).GetField("clientHeight", BindingFlags.NonPublic | BindingFlags.Instance); + + controlBoxForeColor = UIStyles.Blue.FormControlBoxForeColor; + controlBoxFillHoverColor = UIStyles.Blue.FormControlBoxFillHoverColor; + ControlBoxCloseFillHoverColor = UIStyles.Blue.FormControlBoxCloseFillHoverColor; + rectColor = UIStyles.Blue.FormRectColor; + ForeColor = UIStyles.Blue.FormForeColor; + titleColor = UIStyles.Blue.FormTitleColor; + titleForeColor = UIStyles.Blue.FormTitleForeColor; + } + + [Browsable(false)] + public new bool IsMdiContainer + { + get => base.IsMdiContainer; + set => base.IsMdiContainer = false; + } + + [Browsable(false)] + public new bool AutoScroll + { + get => base.AutoScroll; + set => base.AutoScroll = false; + } + + [DefaultValue(true)] + [Description("是否点击标题栏可以移动窗体"), Category("SunnyUI")] + public bool Movable { get; set; } = true; + + + [DefaultValue(false)] + [Description("允许在标题栏放置控件"), Category("SunnyUI")] + public bool AllowAddControlOnTitle + { + get; set; + } + + [DefaultValue(false)] + [Description("允许显示标题栏"), Category("SunnyUI")] + public bool AllowShowTitle + { + get => ShowTitle; + set => ShowTitle = value; + } + + private bool extendBox; + + [DefaultValue(false)] + [Description("显示扩展按钮"), Category("SunnyUI")] + public bool ExtendBox + { + get => extendBox; + set + { + extendBox = value; + CalcSystemBoxPos(); + Invalidate(); + } + } + + /// + /// 是否显示窗体的标题栏 + /// + private bool showTitle = true; + + /// + /// 是否显示窗体的标题栏 + /// + [Description("是否显示窗体的标题栏"), Category("WindowStyle"), DefaultValue(true)] + public bool ShowTitle + { + get => showTitle; + set + { + showTitle = value; + Padding = new Padding(Padding.Left, value ? titleHeight : 0, Padding.Right, Padding.Bottom); + Invalidate(); + } + } + + private int extendSymbol = 0; + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + [Editor("Sunny.UI.UIImagePropertyEditor, " + AssemblyRefEx.SystemDesign, typeof(UITypeEditor))] + [DefaultValue(0)] + [Description("扩展按钮字体图标"), Category("SunnyUI")] + public int ExtendSymbol + { + get => extendSymbol; + set + { + extendSymbol = value; + Invalidate(); + } + } + + private int _symbolSize = 24; + + [DefaultValue(24)] + [Description("扩展按钮字体图标大小"), Category("SunnyUI")] + public int ExtendSymbolSize + { + get => _symbolSize; + set + { + _symbolSize = Math.Max(value, 16); + _symbolSize = Math.Min(value, 128); + Invalidate(); + } + } + + private Point extendSymbolOffset = new Point(0, 0); + + [DefaultValue(typeof(Point), "0, 0")] + [Description("扩展按钮字体图标偏移量"), Category("SunnyUI")] + public Point ExtendSymbolOffset + { + get => extendSymbolOffset; + set + { + extendSymbolOffset = value; + Invalidate(); + } + } + + [DefaultValue(null)] + [Description("扩展按钮菜单"), Category("SunnyUI")] + public UIContextMenuStrip ExtendMenu + { + get; set; + } + + /// + /// 是否显示窗体的控制按钮 + /// + private bool controlBox = true; + + /// + /// 是否显示窗体的控制按钮 + /// + [Description("是否显示窗体的控制按钮"), Category("WindowStyle"), DefaultValue(true)] + public new bool ControlBox + { + get => controlBox; + set + { + controlBox = value; + if (!controlBox) + { + MinimizeBox = MaximizeBox = false; + } + + CalcSystemBoxPos(); + Invalidate(); + } + } + + /// + /// 是否显示窗体的最大化按钮 + /// + [Description("是否显示窗体的最大化按钮"), Category("WindowStyle"), DefaultValue(true)] + public new bool MaximizeBox + { + get => maximizeBox; + set + { + maximizeBox = value; + if (value) minimizeBox = true; + CalcSystemBoxPos(); + Invalidate(); + } + } + + /// + /// 是否显示窗体的最大化按钮 + /// + private bool maximizeBox = true; + + /// + /// 是否显示窗体的最小化按钮 + /// + private bool minimizeBox = true; + + /// + /// 是否显示窗体的最小化按钮 + /// + [Description("是否显示窗体的最小化按钮"), Category("WindowStyle"), DefaultValue(true)] + public new bool MinimizeBox + { + get => minimizeBox; + set + { + minimizeBox = value; + if (!value) maximizeBox = false; + CalcSystemBoxPos(); + Invalidate(); + } + } + + private bool showFullScreen = false; + + /// + /// 是否以全屏模式进入最大化 + /// + [Description("是否以全屏模式进入最大化"), Category("WindowStyle")] + public bool ShowFullScreen + { + get => showFullScreen; + set + { + showFullScreen = value; + base.MaximumSize = ShowFullScreen ? Screen.PrimaryScreen.Bounds.Size : Screen.PrimaryScreen.WorkingArea.Size; + } + } + + /// + /// 标题栏高度 + /// + private int titleHeight = 35; + + /// + /// 标题栏高度 + /// + [Description("标题栏高度"), Category("SunnyUI"), DefaultValue(35)] + public int TitleHeight + { + get => titleHeight; + set + { + titleHeight = Math.Max(value, 29); + Padding = new Padding(Padding.Left, showTitle ? titleHeight : Padding.Top, Padding.Right, Padding.Bottom); + Invalidate(); + CalcSystemBoxPos(); + } + } + + private Color titleColor; + + /// + /// 标题栏颜色 + /// + [Description("标题栏颜色"), Category("SunnyUI"), DefaultValue(typeof(Color), "80, 160, 255")] + public Color TitleColor + { + get => titleColor; + set + { + if (titleColor != value) + { + titleColor = value; + Invalidate(); + } + } + } + + /// + /// 标题颜色 + /// + private Color titleForeColor; + + /// + /// 标题颜色 + /// + [Description("标题前景色(标题颜色)"), Category("SunnyUI"), DefaultValue(typeof(Color), "White")] + public Color TitleForeColor + { + get => titleForeColor; + set + { + if (titleForeColor != value) + { + titleForeColor = value; + Invalidate(); + } + } + } + + /// + /// 标题字体 + /// + private Font titleFont = UIStyles.Font(); + + /// + /// 标题字体 + /// + [Description("标题字体"), Category("SunnyUI")] + [DefaultValue(typeof(Font), "宋体, 12pt")] + public Font TitleFont + { + get => titleFont; + set + { + titleFont = value; + Invalidate(); + } + } + + /// + /// 当前控件的版本 + /// + [Description("控件版本"), Category("SunnyUI")] + public string Version + { + get; + } + + private Rectangle ControlBoxRect; + + private Rectangle MaximizeBoxRect; + + private Rectangle MinimizeBoxRect; + + private Rectangle ExtendBoxRect; + + private int ControlBoxLeft; + + private void CalcSystemBoxPos() + { + ControlBoxLeft = Width; + + if (ControlBox) + { + if (WindowState == FormWindowState.Maximized) + { + ControlBoxRect = new Rectangle(Width - 6 - 28 - 16, titleHeight / 2 - 14, 28, 28); + } + else + { + ControlBoxRect = new Rectangle(Width - 6 - 28, titleHeight / 2 - 14, 28, 28); + } + + ControlBoxLeft = ControlBoxRect.Left - 2; + + if (MaximizeBox) + { + MaximizeBoxRect = new Rectangle(ControlBoxRect.Left - 28 - 2, ControlBoxRect.Top, 28, 28); + ControlBoxLeft = MaximizeBoxRect.Left - 2; + } + else + { + MaximizeBoxRect = new Rectangle(Width + 1, Height + 1, 1, 1); + } + + if (MinimizeBox) + { + MinimizeBoxRect = new Rectangle(MaximizeBox ? MaximizeBoxRect.Left - 28 - 2 : ControlBoxRect.Left - 28 - 2, ControlBoxRect.Top, 28, 28); + ControlBoxLeft = MinimizeBoxRect.Left - 2; + } + else + { + MinimizeBoxRect = new Rectangle(Width + 1, Height + 1, 1, 1); + } + + if (ExtendBox) + { + if (MinimizeBox) + { + ExtendBoxRect = new Rectangle(MinimizeBoxRect.Left - 28 - 2, ControlBoxRect.Top, 28, 28); + } + else + { + ExtendBoxRect = new Rectangle(ControlBoxRect.Left - 28 - 2, ControlBoxRect.Top, 28, 28); + } + + ControlBoxLeft = ExtendBoxRect.Left - 2; + } + } + else + { + ExtendBoxRect = MaximizeBoxRect = MinimizeBoxRect = ControlBoxRect = new Rectangle(Width + 1, Height + 1, 1, 1); + } + } + + /// + /// 重载控件尺寸变更 + /// + /// 参数 + protected override void OnSizeChanged(EventArgs e) + { + base.OnSizeChanged(e); + CalcSystemBoxPos(); + } + + /// + /// 重载鼠标离开事件 + /// + /// 鼠标参数 + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + InExtendBox = InControlBox = InMaxBox = InMinBox = false; + Invalidate(); + } + + private bool InControlBox, InMaxBox, InMinBox, InExtendBox; + + protected override void OnMouseClick(MouseEventArgs e) + { + if (ShowTitle) + { + if (InControlBox) + { + InControlBox = false; + Close(); + } + + if (InMinBox) + { + InMinBox = false; + WindowState = FormWindowState.Minimized; + } + + if (InMaxBox) + { + InMaxBox = false; + if (!showFullScreen) + { + if (WindowState == FormWindowState.Maximized) + { + WindowState = FormWindowState.Normal; + if (Location.Y < 0) Location = new Point(Location.X, 0); + } + else + { + WindowState = FormWindowState.Maximized; + } + } + else + { + if (WindowState == FormWindowState.Maximized) + { + FormBorderStyle = FormBorderStyle.Sizable; + WindowState = FormWindowState.Normal; + if (Location.Y < 0) Location = new Point(Location.X, 0); + } + else + { + FormBorderStyle = FormBorderStyle.None; + WindowState = FormWindowState.Maximized; + } + } + } + + if (InExtendBox) + { + InExtendBox = false; + if (ExtendMenu != null) + { + this.ShowContextMenuStrip(ExtendMenu, ExtendBoxRect.Left, TitleHeight - 1); + } + else + { + ExtendBoxClick?.Invoke(this, EventArgs.Empty); + } + } + } + } + + /// + /// 重载鼠标按下事件f + /// + /// 鼠标参数 + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + if (InControlBox || InMaxBox || InMinBox || InExtendBox) return; + if (!ShowTitle) return; + if (e.Y > Padding.Top) return; + if (e.X > ControlBoxLeft) return; + if (!Movable) return; + + Win32.User.ReleaseCapture(); + Win32.User.SendMessage(this.Handle, Win32.User.WM_SYSCOMMAND, Win32.User.SC_MOVE + Win32.User.HTCAPTION, 0); + } + + /// + /// 重载鼠标移动事件 + /// + /// 鼠标参数 + protected override void OnMouseMove(MouseEventArgs e) + { + bool inControlBox = e.Location.InRect(ControlBoxRect); + if (WindowState == FormWindowState.Maximized && ControlBox) + { + if (e.Location.X > ControlBoxRect.Left && e.Location.Y < TitleHeight) + inControlBox = true; + } + + bool inMaxBox = e.Location.InRect(MaximizeBoxRect); + bool inMinBox = e.Location.InRect(MinimizeBoxRect); + bool inExtendBox = e.Location.InRect(ExtendBoxRect); + bool isChange = false; + + if (inControlBox != InControlBox) + { + InControlBox = inControlBox; + isChange = true; + } + + if (inMaxBox != InMaxBox) + { + InMaxBox = inMaxBox; + isChange = true; + } + + if (inMinBox != InMinBox) + { + InMinBox = inMinBox; + isChange = true; + } + + if (inExtendBox != InExtendBox) + { + InExtendBox = inExtendBox; + isChange = true; + } + + if (isChange) + { + Invalidate(); + } + + base.OnMouseMove(e); + } + + private Color controlBoxForeColor = Color.White; + /// + /// 标题栏颜色 + /// + [Description("标题栏按钮颜色"), Category("SunnyUI"), DefaultValue(typeof(Color), "White")] + public Color ControlBoxForeColor + { + get => controlBoxForeColor; + set + { + if (controlBoxForeColor != value) + { + controlBoxForeColor = value; + Invalidate(); + } + } + } + + protected Color rectColor; + + /// + /// 边框颜色 + /// + /// The color of the border style. + [Description("边框颜色"), Category("SunnyUI")] + public Color RectColor + { + get => rectColor; + set + { + rectColor = value; + AfterSetRectColor(value); + RectColorChanged?.Invoke(this, EventArgs.Empty); + Invalidate(); + } + } + + private Color controlBoxCloseFillHoverColor; + /// + /// 标题栏颜色 + /// + [Description("标题栏关闭按钮移上背景颜色"), Category("SunnyUI"), DefaultValue(typeof(Color), "Red")] + public Color ControlBoxCloseFillHoverColor + { + get => controlBoxCloseFillHoverColor; + set + { + if (controlBoxCloseFillHoverColor != value) + { + controlBoxCloseFillHoverColor = value; + Invalidate(); + } + } + } + + private Color controlBoxFillHoverColor; + /// + /// 标题栏颜色 + /// + [Description("标题栏按钮移上背景颜色"), Category("SunnyUI"), DefaultValue(typeof(Color), "115, 179, 255")] + public Color ControlBoxFillHoverColor + { + get => controlBoxFillHoverColor; + set + { + if (ControlBoxFillHoverColor != value) + { + controlBoxFillHoverColor = value; + Invalidate(); + } + } + } + + protected virtual void AfterSetRectColor(Color color) { } + + public event EventHandler RectColorChanged; + + /// + /// 是否重绘边框样式 + /// + private bool _showRect = true; + + /// + /// 是否显示边框 + /// + [Description("是否显示边框"), Category("SunnyUI")] + [DefaultValue(true)] + public bool ShowRect + { + get => _showRect; + set + { + _showRect = value; + Invalidate(); + } + } + + /// + /// 重载绘图 + /// + /// 绘图参数 + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + if (Width <= 0 || Height <= 0) + { + return; + } + + if (ShowTitle) + { + e.Graphics.FillRectangle(titleColor, 0, 0, Width, TitleHeight); + e.Graphics.DrawLine(RectColor, 0, titleHeight, Width, titleHeight); + } + + if (ShowRect) + { + Point[] points = new[] + { + new Point(0, 0), + new Point(Width - 1, 0), + new Point(Width - 1, Height - 1), + new Point(0, Height - 1), + new Point(0, 0) + }; + + e.Graphics.DrawLines(rectColor, points); + e.Graphics.DrawLine(Color.FromArgb(120, rectColor), new Point(2, 1), new Point(1, 2)); + e.Graphics.DrawLine(Color.FromArgb(120, rectColor), new Point(2, Height - 1 - 1), new Point(1, Height - 1 - 2)); + e.Graphics.DrawLine(Color.FromArgb(120, rectColor), new Point(Width - 1 - 2, 1), new Point(Width - 1 - 1, 2)); + e.Graphics.DrawLine(Color.FromArgb(120, rectColor), new Point(Width - 1 - 2, Height - 1 - 1), new Point(Width - 1 - 1, Height - 1 - 2)); + } + + if (!ShowTitle) + { + return; + } + + e.Graphics.SetHighQuality(); + if (ControlBox) + { + if (InControlBox) + { + if (WindowState == FormWindowState.Maximized) + { + e.Graphics.FillRectangle(ControlBoxCloseFillHoverColor, new Rectangle(ControlBoxRect.Left, 0, Width - ControlBoxRect.Left, TitleHeight)); + } + else + { + e.Graphics.FillRectangle(ControlBoxCloseFillHoverColor, ControlBoxRect); + } + } + + e.Graphics.DrawLine(controlBoxForeColor, + ControlBoxRect.Left + ControlBoxRect.Width / 2 - 5, + ControlBoxRect.Top + ControlBoxRect.Height / 2 - 5, + ControlBoxRect.Left + ControlBoxRect.Width / 2 + 5, + ControlBoxRect.Top + ControlBoxRect.Height / 2 + 5); + e.Graphics.DrawLine(controlBoxForeColor, + ControlBoxRect.Left + ControlBoxRect.Width / 2 - 5, + ControlBoxRect.Top + ControlBoxRect.Height / 2 + 5, + ControlBoxRect.Left + ControlBoxRect.Width / 2 + 5, + ControlBoxRect.Top + ControlBoxRect.Height / 2 - 5); + } + + if (MaximizeBox) + { + if (InMaxBox) + { + e.Graphics.FillRectangle(ControlBoxFillHoverColor, MaximizeBoxRect); + } + + if (WindowState == FormWindowState.Maximized) + { + e.Graphics.DrawRectangle(controlBoxForeColor, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 5, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 1, + 7, 7); + + e.Graphics.DrawLine(controlBoxForeColor, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 2, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 1, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 2, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 4); + + e.Graphics.DrawLine(controlBoxForeColor, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 2, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 4, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 + 5, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 4); + + e.Graphics.DrawLine(controlBoxForeColor, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 + 5, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 4, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 + 5, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 + 3); + + e.Graphics.DrawLine(controlBoxForeColor, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 + 5, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 + 3, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 + 3, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 + 3); + } + + if (WindowState == FormWindowState.Normal) + { + e.Graphics.DrawRectangle(controlBoxForeColor, + MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 5, + MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 - 4, + 10, 9); + } + } + + if (MinimizeBox) + { + if (InMinBox) + { + e.Graphics.FillRectangle(ControlBoxFillHoverColor, MinimizeBoxRect); + } + + e.Graphics.DrawLine(controlBoxForeColor, + MinimizeBoxRect.Left + MinimizeBoxRect.Width / 2 - 6, + MinimizeBoxRect.Top + MinimizeBoxRect.Height / 2, + MinimizeBoxRect.Left + MinimizeBoxRect.Width / 2 + 5, + MinimizeBoxRect.Top + MinimizeBoxRect.Height / 2); + } + + if (ExtendBox) + { + if (InExtendBox) + { + e.Graphics.FillRectangle(ControlBoxFillHoverColor, ExtendBoxRect); + } + + if (ExtendSymbol == 0) + { + e.Graphics.DrawLine(controlBoxForeColor, + ExtendBoxRect.Left + ExtendBoxRect.Width / 2 - 5 - 1, + ExtendBoxRect.Top + ExtendBoxRect.Height / 2 - 2, + ExtendBoxRect.Left + ExtendBoxRect.Width / 2 - 1, + ExtendBoxRect.Top + ExtendBoxRect.Height / 2 + 3); + + e.Graphics.DrawLine(controlBoxForeColor, + ExtendBoxRect.Left + ExtendBoxRect.Width / 2 + 5 - 1, + ExtendBoxRect.Top + ExtendBoxRect.Height / 2 - 2, + ExtendBoxRect.Left + ExtendBoxRect.Width / 2 - 1, + ExtendBoxRect.Top + ExtendBoxRect.Height / 2 + 3); + } + else + { + e.Graphics.DrawFontImage(extendSymbol, ExtendSymbolSize, controlBoxForeColor, ExtendBoxRect, ExtendSymbolOffset.X, ExtendSymbolOffset.Y); + } + } + + e.Graphics.SetDefaultQuality(); + + if (ShowTitleIcon && Icon != null) + { + using (Image image = IconToImage(Icon)) + { + e.Graphics.DrawImage(image, 6, (TitleHeight - 24) / 2, 24, 24); + } + } + + if (TextAlignment == StringAlignment.Center) + { + e.Graphics.DrawString(Text, TitleFont, titleForeColor, new Rectangle(0, 0, Width, TitleHeight), ContentAlignment.MiddleCenter); + } + else + { + e.Graphics.DrawString(Text, TitleFont, titleForeColor, new Rectangle(6 + (ShowTitleIcon && Icon != null ? 26 : 0), 0, Width, TitleHeight), ContentAlignment.MiddleLeft); + } + } + + private StringAlignment textAlignment = StringAlignment.Near; + + [Description("文字对齐方式"), Category("SunnyUI")] + public StringAlignment TextAlignment + { + get => textAlignment; + set + { + textAlignment = value; + Invalidate(); + } + } + + private Image IconToImage(Icon icon) + { + MemoryStream mStream = new MemoryStream(); + icon.Save(mStream); + Image image = Image.FromStream(mStream); + return image; + } + + private bool showTitleIcon; + + [Description("显示标题栏图标"), Category("SunnyUI")] + [DefaultValue(false)] + public bool ShowTitleIcon + { + get => showTitleIcon; + set + { + showTitleIcon = value; + Invalidate(); + } + } + + public event EventHandler ExtendBoxClick; + + private FieldInfo fieldW; + private FieldInfo fieldH; + private bool boundsCoreState = false; + + protected override void SetClientSizeCore(int x, int y) + { + if (DesignMode && fieldW != null && fieldH != null) + { + fieldW.SetValue(this, x); + fieldH.SetValue(this, y); + OnClientSizeChanged(EventArgs.Empty); + Size = SizeFromClientSize(new Size(x, y)); + } + else + { + base.SetClientSizeCore(x, y); + } + } + + protected Padding GetNonClientMetrics() + { + var screenRect = ClientRectangle; + screenRect.Offset(-Bounds.Left, -Bounds.Top); + var rect = new RECT(screenRect.Left, screenRect.Top, screenRect.Right, screenRect.Bottom); + Win32.User.AdjustWindowRectEx(ref rect, (int)CreateParams.Style, false, (int)CreateParams.ExStyle); + return new Padding + { + Top = screenRect.Top - rect.Top, + Left = screenRect.Left - rect.Left, + Bottom = rect.Bottom - screenRect.Bottom, + Right = rect.Right - screenRect.Right + }; + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (boundsCoreState && base.WindowState != FormWindowState.Minimized) + { + if (y != Top) y = Top; + if (x != Left) x = Left; + boundsCoreState = false; + } + + var size = SetBoundsCore(width, height); + base.SetBoundsCore(x, y, size.Width, size.Height, specified); + } + + private Size SetBoundsCore(int width, int height) + { + if (base.WindowState == FormWindowState.Normal) + { + var boundsSpecified = typeof(Form).GetField("restoredWindowBoundsSpecified", BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(Form).GetField("_restoredWindowBoundsSpecified", BindingFlags.NonPublic | BindingFlags.Instance); + var restoredSpecified = (BoundsSpecified)boundsSpecified!.GetValue(this)!; + + if ((restoredSpecified & BoundsSpecified.Size) != BoundsSpecified.None) + { + var boundsField = typeof(Form).GetField("FormStateExWindowBoundsWidthIsClientSize", BindingFlags.NonPublic | BindingFlags.Static); + var stateField = typeof(Form).GetField("formStateEx", BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(Form).GetField("_formStateEx", BindingFlags.NonPublic | BindingFlags.Instance); + var restoredField = typeof(Form).GetField("restoredWindowBounds", BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(Form).GetField("_restoredWindowBounds", BindingFlags.NonPublic | BindingFlags.Instance); + + if (boundsField != null && stateField != null && restoredField != null) + { + var restoredBounds = (Rectangle)restoredField.GetValue(this)!; + var section = (BitVector32.Section)boundsField.GetValue(this)!; + var vector = (BitVector32)stateField.GetValue(this)!; + if (vector[section] == 1) + { + width = restoredBounds.Width; + height = restoredBounds.Height; + } + } + } + } + + return new Size(width, height); + } + + protected override void WndProc(ref Message m) + { + var msg = (int)m.Msg; + switch (msg) + { + case Win32.User.WM_ACTIVATE: + var margins = new Win32.Dwm.MARGINS(0, 0, 1, 0); + Win32.Dwm.DwmExtendFrameIntoClientArea(Handle, ref margins); + break; + case Win32.User.WM_NCCALCSIZE when m.WParam != IntPtr.Zero: + if (CalcSize(ref m)) return; + break; + } + + base.WndProc(ref m); + } + + private bool CalcSize(ref Message m) + { + if (FormBorderStyle == FormBorderStyle.None) return false; +#if NET40 + var sizeParams = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS)); +#else + var sizeParams = Marshal.PtrToStructure(m.LParam); +#endif + var borders = GetNonClientMetrics(); + + if (Win32.User.IsZoomed(Handle) == 1) + { + sizeParams.rgrc0.Top -= borders.Top; + sizeParams.rgrc0.Top += borders.Bottom; + Marshal.StructureToPtr(sizeParams, m.LParam, false); + } + else + { + m.Result = new IntPtr(1); + return true; + } + + m.Result = new IntPtr(0x0400); + return false; + } + + protected override void OnShown(EventArgs e) + { + base.OnShown(e); + + //if (AutoScaleMode == AutoScaleMode.Font) AutoScaleMode = AutoScaleMode.None; + //if (base.BackColor == SystemColors.Control) base.BackColor = UIStyles.Blue.PageBackColor; + + //Render(); + CalcSystemBoxPos(); + //IsShown = true; + //SetDPIScale(); + //SetZoomScaleRect(); + // + //if (AfterShown != null) + //{ + // AfterShownTimer = new System.Windows.Forms.Timer(); + // AfterShownTimer.Tick += AfterShownTimer_Tick; + // AfterShownTimer.Start(); + //} + } + } +} diff --git a/SunnyUI/Forms/UIForm2.resx b/SunnyUI/Forms/UIForm2.resx new file mode 100644 index 00000000..af32865e --- /dev/null +++ b/SunnyUI/Forms/UIForm2.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SunnyUI/Win32/Win32.Added.cs b/SunnyUI/Win32/Win32.Added.cs index 8f159535..ccab7689 100644 --- a/SunnyUI/Win32/Win32.Added.cs +++ b/SunnyUI/Win32/Win32.Added.cs @@ -136,6 +136,18 @@ namespace Sunny.UI.Win32 [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); + + [DllImport("user32.dll", SetLastError = true, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AdjustWindowRectEx(ref RECT lpRect, int dwStyle, [MarshalAs(UnmanagedType.Bool)] bool bMenu, int dwExStyle); + + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NCCALCSIZE_PARAMS + { + public RECT rgrc0, rgrc1, rgrc2; + public WINDOWPOS lppos; } public class Dwm @@ -155,6 +167,14 @@ namespace Sunny.UI.Win32 public int rightWidth; public int topHeight; public int bottomHeight; + + public MARGINS(int left, int right, int top, int bottom) + { + leftWidth = left; + rightWidth = right; + topHeight = top; + bottomHeight = bottom; + } } }