diff --git a/Bin/SunnyUI.dll b/Bin/SunnyUI.dll
index f0935255..8fbcfd6f 100644
Binary files a/Bin/SunnyUI.dll and b/Bin/SunnyUI.dll differ
diff --git a/Bin/SunnyUI.pdb b/Bin/SunnyUI.pdb
index 270df6dd..24359ed0 100644
Binary files a/Bin/SunnyUI.pdb and b/Bin/SunnyUI.pdb differ
diff --git a/SunnyUI.Demo/Bin/SunnyUI.Demo.exe b/SunnyUI.Demo/Bin/SunnyUI.Demo.exe
index afbf4e2f..23fa8877 100644
Binary files a/SunnyUI.Demo/Bin/SunnyUI.Demo.exe and b/SunnyUI.Demo/Bin/SunnyUI.Demo.exe differ
diff --git a/SunnyUI.Demo/Bin/SunnyUI.dll b/SunnyUI.Demo/Bin/SunnyUI.dll
index f0935255..8fbcfd6f 100644
Binary files a/SunnyUI.Demo/Bin/SunnyUI.dll and b/SunnyUI.Demo/Bin/SunnyUI.dll differ
diff --git a/SunnyUI.Demo/FMain.Designer.cs b/SunnyUI.Demo/FMain.Designer.cs
index 14d4b190..74338fd4 100644
--- a/SunnyUI.Demo/FMain.Designer.cs
+++ b/SunnyUI.Demo/FMain.Designer.cs
@@ -37,7 +37,6 @@
this.uiLogo1 = new Sunny.UI.UILogo();
this.uiAvatar = new Sunny.UI.UIAvatar();
this.StyleManager = new Sunny.UI.UIStyleManager(this.components);
- this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.Header.SuspendLayout();
this.SuspendLayout();
//
@@ -46,17 +45,18 @@
this.Aside.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240)))));
this.Aside.ItemHeight = 36;
this.Aside.LineColor = System.Drawing.Color.Black;
+ this.Aside.Location = new System.Drawing.Point(2, 145);
this.Aside.MenuStyle = Sunny.UI.UIMenuStyle.Black;
this.Aside.ShowOneNode = true;
this.Aside.ShowTips = true;
- this.Aside.Size = new System.Drawing.Size(250, 575);
+ this.Aside.Size = new System.Drawing.Size(250, 573);
this.Aside.Style = Sunny.UI.UIStyle.Custom;
//
// Header
//
this.Header.Controls.Add(this.uiAvatar);
this.Header.Controls.Add(this.uiLogo1);
- this.Header.ImageList = this.imageList1;
+ this.Header.Location = new System.Drawing.Point(2, 35);
treeNode1.ImageIndex = 1;
treeNode1.Name = "节点0";
treeNode1.Text = "控件";
@@ -72,7 +72,7 @@
treeNode3,
treeNode4});
this.Header.SelectedIndex = 0;
- this.Header.Size = new System.Drawing.Size(1024, 110);
+ this.Header.Size = new System.Drawing.Size(1020, 110);
this.Header.Style = Sunny.UI.UIStyle.Custom;
this.Header.MenuItemClick += new Sunny.UI.UINavBar.OnMenuItemClick(this.Header_MenuItemClick);
//
@@ -92,19 +92,12 @@
//
this.uiAvatar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.uiAvatar.Font = new System.Drawing.Font("微软雅黑", 12F);
- this.uiAvatar.Location = new System.Drawing.Point(943, 25);
+ this.uiAvatar.Location = new System.Drawing.Point(939, 25);
this.uiAvatar.Name = "uiAvatar";
this.uiAvatar.Size = new System.Drawing.Size(66, 70);
this.uiAvatar.TabIndex = 4;
this.uiAvatar.Text = "uiAvatar1";
//
- // imageList1
- //
- this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
- this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
- this.imageList1.Images.SetKeyName(0, "002.png");
- this.imageList1.Images.SetKeyName(1, "025.png");
- //
// FMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
@@ -112,8 +105,10 @@
this.ClientSize = new System.Drawing.Size(1024, 720);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FMain";
+ this.Padding = new System.Windows.Forms.Padding(2, 35, 2, 2);
+ this.ShowDragStretch = true;
+ this.ShowRadius = false;
this.Text = "SunnyUI.Net";
- this.WindowStateChange += new Sunny.UI.UIForm.OnWindowStateChange(this.FMain_WindowStateChange);
this.Header.ResumeLayout(false);
this.ResumeLayout(false);
@@ -124,6 +119,5 @@
private UILogo uiLogo1;
private UIAvatar uiAvatar;
private UIStyleManager StyleManager;
- private System.Windows.Forms.ImageList imageList1;
}
}
\ No newline at end of file
diff --git a/SunnyUI.Demo/FMain.resx b/SunnyUI.Demo/FMain.resx
index a8d2899d..8afef9d3 100644
--- a/SunnyUI.Demo/FMain.resx
+++ b/SunnyUI.Demo/FMain.resx
@@ -117,56 +117,6 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 150, 17
-
-
-
- AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
- LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABS
- CQAAAk1TRnQBSQFMAgEBAgEAARABAAEQAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
- AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
- AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
- AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
- AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
- AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM
- AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA
- ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz
- AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ
- AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM
- AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA
- AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA
- AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ
- AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/
- AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA
- AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm
- ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ
- Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz
- AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA
- AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM
- AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM
- ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM
- Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA
- AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM
- AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ
- AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
- AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
- AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
- AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/xIAAW8BJQFGAUwCbwKT
- Am8BTAFGASUBbzIAAbQMGQG0IQABCQK0AQkBAAEJBLQBCQEAAQkCtAEJAQABtAH0CgcB9AG0IQABtAIZ
- AbUBiwG1BBkBtQGLAbUCGQG0AQABtAH0AQcC/wEHAv8BBwL/AQcB9AG0IQABtA4ZAbQBAAG0AfQKBwH0
- AbQhAAG0AfQGCQH0AfEB8AG8AgcB9AG0AQABuwH0AQcC/wEHAv8BBwL/AQcB9AG7IQABtAH0ARkBCQK0
- AQkBGQf0AbQBAAHcAf8KBwH/AdwhAAG6AfQBGQGLAkwBiwEZAfQB8QHwAbwCBwH0AboBAAHcAf8BTwKe
- AZcCngGXAp4BTwH/AdwhAAHcAf8BtAFSAsMBUgG0B/8B3AEAAdwB/wNPAZcCTwGXA08B/wHcIQAB3AH/
- AbQBdQL2AXUBtAH/AfEB8AG8AgcB/wHcAQAB3Az/AdwhAAHcAf8B1QIiAZoBIgHVB/8B3AEADiUhAAHc
- Af8B1QQVAdUB/wLcAbsCtAH/AdwBAAElAUcB3AH/AbQIRwElIQAB3A7/AdwBAAFGAeMBbwHrAW8E4wFv
- AesBbwHjAUYhAAEZAtwCCQYZAgkC3AEZAQABFgFHAewBvAHsBE0B7AG8AewBRwEWNAABkgHzAZIEAAGS
- AfMBkjYAAfEB7wHxBAAB8QHvAfEjAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEBAQABAQUAAYAXAAP/
- AQAC/wGAAQEEAAL/AYABAQQAAQgBEAGAAQEGAAGAAQEGAAGAAQEGAAGAAQEGAAGAAQEGAAGAAQEGAAGA
- AQEGAAGAAQEGAAGAAQEGAAGAAQEGAAGAAQEGAAGAAQEEAAL/AeMBxwQAAv8B4wHHBAAL
-
-
17, 17
diff --git a/SunnyUI/Controls/UINavMenu.cs b/SunnyUI/Controls/UINavMenu.cs
index 7bbb715c..6dd716b4 100644
--- a/SunnyUI/Controls/UINavMenu.cs
+++ b/SunnyUI/Controls/UINavMenu.cs
@@ -40,7 +40,12 @@ namespace Sunny.UI
public UINavMenu()
{
- SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
+ SetStyle(ControlStyles.DoubleBuffer |
+ ControlStyles.AllPaintingInWmPaint |
+ ControlStyles.OptimizedDoubleBuffer, true);
+
+ base.UpdateStyles();
+
BorderStyle = BorderStyle.None;
//HideSelection = false;
DrawMode = TreeViewDrawMode.OwnerDrawAll;
diff --git a/SunnyUI/Forms/UIForm.cs b/SunnyUI/Forms/UIForm.cs
index 620f3188..d6043472 100644
--- a/SunnyUI/Forms/UIForm.cs
+++ b/SunnyUI/Forms/UIForm.cs
@@ -19,7 +19,8 @@
* 2020-01-01: V2.2.0 增加文件说明
* 2020-05-30: V2.2.5 更新标题移动、双击最大化/正常、到顶最大化、最大化后拖拽正常
* 2020-07-01: V2.2.6 仿照QQ,重绘标题栏按钮
- * 2020-07-05: V2.2.6 UIForm:更新窗体控制按钮圆角和跟随窗体圆角变化。
+ * 2020-07-05: V2.2.6 更新窗体控制按钮圆角和跟随窗体圆角变化。
+ * 2020-09-17: V2.2.7 重写WindowState相关代码
******************************************************************************/
using System;
@@ -39,10 +40,6 @@ namespace Sunny.UI
private UIStatusForm statusForm;
- public delegate void OnWindowStateChange(object sender, FormWindowState state);
-
- public event OnWindowStateChange WindowStateChange;
-
public UIForm()
{
InitializeComponent();
@@ -52,11 +49,32 @@ namespace Sunny.UI
SetStyle(UIStyles.Style);
}
- SetStyle(ControlStyles.UserPaint, true);
- SetStyle(ControlStyles.AllPaintingInWmPaint, true);
- SetStyle(ControlStyles.DoubleBuffer, true);
+ base.SetStyle(
+ ControlStyles.UserPaint |
+ ControlStyles.DoubleBuffer |
+ ControlStyles.OptimizedDoubleBuffer |
+ ControlStyles.AllPaintingInWmPaint |
+ ControlStyles.ResizeRedraw |
+ ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
+
Version = UIGlobal.Version;
+ FormBorderStyle = FormBorderStyle.None;
+ base.MaximumSize = ShowFullScreen ? Screen.PrimaryScreen.Bounds.Size : Screen.PrimaryScreen.WorkingArea.Size;
+ }
+
+ //不显示FormBorderStyle属性
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public new FormBorderStyle FormBorderStyle
+ {
+ get { return base.FormBorderStyle; }
+ set
+ {
+ base.FormBorderStyle = FormBorderStyle.None;
+ Console.WriteLine(value);
+ }
}
public void Render()
@@ -357,8 +375,7 @@ namespace Sunny.UI
if (MinimizeBox)
{
- MinimizeBoxRect = new Rectangle(MaximizeBox ? MaximizeBoxRect.Left - 28 - 2 : ControlBoxRect.Left - 28 - 2,
- ControlBoxRect.Top, 28, 28);
+ MinimizeBoxRect = new Rectangle(MaximizeBox ? MaximizeBoxRect.Left - 28 - 2 : ControlBoxRect.Left - 28 - 2, ControlBoxRect.Top, 28, 28);
ControlBoxLeft = MinimizeBoxRect.Left - 2;
}
else
@@ -458,21 +475,20 @@ namespace Sunny.UI
{
if (InControlBox)
{
- Close();
InControlBox = false;
+ Close();
}
if (InMinBox)
{
- base.WindowState = FormWindowState.Minimized;
- WindowStateChange?.Invoke(this, FormWindowState.Minimized);
InMinBox = false;
+ WindowState = FormWindowState.Minimized;
}
if (InMaxBox)
{
- ShowMaximize();
InMaxBox = false;
+ ShowMaximize();
}
}
}
@@ -490,7 +506,8 @@ namespace Sunny.UI
private void ShowMaximize(bool IsOnMoving = false)
{
Screen screen = Screen.FromPoint(MousePosition);
- if (windowState == FormWindowState.Normal)
+ base.MaximumSize = ShowFullScreen ? Screen.PrimaryScreen.Bounds.Size : Screen.PrimaryScreen.WorkingArea.Size;
+ if (WindowState == FormWindowState.Normal)
{
size = Size;
// 若窗体从正常模式->最大化模式,该操作是由移动窗体至顶部触发的,记录的是移动前的窗体位置
@@ -500,11 +517,9 @@ namespace Sunny.UI
Left = screen.Bounds.Left;
Top = screen.Bounds.Top;
SetFormRoundRectRegion(this, 0);
- if (ShowFullScreen) base.WindowState = FormWindowState.Maximized;
- windowState = FormWindowState.Maximized;
- WindowStateChange?.Invoke(this, FormWindowState.Maximized);
+ WindowState = FormWindowState.Maximized;
}
- else if (windowState == FormWindowState.Maximized)
+ else if (WindowState == FormWindowState.Maximized)
{
if (size.Width == 0 || size.Height == 0)
{
@@ -516,11 +531,9 @@ namespace Sunny.UI
screen.Bounds.Top + screen.WorkingArea.Height / 2 - Size.Height / 2);
if (location.X == 0 && location.Y == 0) location = center;
- Location = StartPosition == FormStartPosition.CenterScreen ? center : location;
+ Location = location;
SetFormRoundRectRegion(this, ShowRadius ? 5 : 0);
- windowState = FormWindowState.Normal;
- base.WindowState = FormWindowState.Normal;
- WindowStateChange?.Invoke(this, FormWindowState.Normal);
+ WindowState = FormWindowState.Normal;
}
Invalidate();
@@ -625,7 +638,7 @@ namespace Sunny.UI
{
if (FormMoveMouseDown && !MousePosition.Equals(mouseOffset))
{
- if (windowState == FormWindowState.Maximized)
+ if (WindowState == FormWindowState.Maximized)
{
int MaximizedWidth = Width;
int LocationX = Left;
@@ -695,6 +708,8 @@ namespace Sunny.UI
InControlBox = InMaxBox = InMinBox = false;
}
}
+
+ base.OnMouseMove(e);
}
protected override void OnMouseLeave(EventArgs e)
@@ -754,7 +769,7 @@ namespace Sunny.UI
if (ShowRect)
{
Point[] points;
- bool unShowRadius = !ShowRadius || windowState == FormWindowState.Maximized ||
+ bool unShowRadius = !ShowRadius || WindowState == FormWindowState.Maximized ||
(Width == Screen.PrimaryScreen.WorkingArea.Width &&
Height == Screen.PrimaryScreen.WorkingArea.Height);
if (unShowRadius)
@@ -840,7 +855,7 @@ namespace Sunny.UI
// ? FontAwesomeIcons.fa_window_restore
// : FontAwesomeIcons.fa_window_maximize, 24, Color.White, MaximizeBoxRect, 1);
- if (windowState == FormWindowState.Maximized)
+ if (WindowState == FormWindowState.Maximized)
{
e.Graphics.DrawRectangle(Color.White,
MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 5,
@@ -872,7 +887,7 @@ namespace Sunny.UI
MaximizeBoxRect.Top + MaximizeBoxRect.Height / 2 + 3);
}
- if (windowState == FormWindowState.Normal)
+ if (WindowState == FormWindowState.Normal)
{
e.Graphics.DrawRectangle(Color.White,
MaximizeBoxRect.Left + MaximizeBoxRect.Width / 2 - 5,
@@ -1137,7 +1152,7 @@ namespace Sunny.UI
/// The instance containing the event data.
private void CtrlMouseDown(object sender, MouseEventArgs e)
{
- if (windowState == FormWindowState.Maximized)
+ if (WindowState == FormWindowState.Maximized)
{
return;
}
@@ -1162,7 +1177,7 @@ namespace Sunny.UI
return;
}
- if (windowState == FormWindowState.Maximized)
+ if (WindowState == FormWindowState.Maximized)
{
SetFormRoundRectRegion(this, 0);
}
@@ -1200,35 +1215,15 @@ namespace Sunny.UI
public string CloseAskString { get; set; }
- private FormWindowState windowState = FormWindowState.Normal;
-
- public new FormWindowState WindowState
- {
- get => windowState;
- set
- {
- if (value == FormWindowState.Minimized)
- {
- base.WindowState = FormWindowState.Minimized;
- return;
- }
-
- ShowMaximize();
- windowState = value;
- }
- }
-
protected override CreateParams CreateParams
{
get
{
- if (this.FormBorderStyle == FormBorderStyle.None)
+ if (base.FormBorderStyle == FormBorderStyle.None)
{
- // 当边框样式为FormBorderStyle.None时
// 点击窗体任务栏图标,可以进行最小化
- const int WS_MINIMIZEBOX = 0x00020000;
CreateParams cp = base.CreateParams;
- cp.Style = cp.Style | WS_MINIMIZEBOX;
+ cp.Style |= 0x00020000;
return cp;
}
else
@@ -1238,27 +1233,67 @@ namespace Sunny.UI
}
}
- public void Show(FormWindowState state)
+ private bool showDragStretch;
+ [Description("显示边框可拖拽调整窗体大小"), Category("SunnyUI"), DefaultValue(false)]
+ public bool ShowDragStretch
{
- ShowFullScreen = false;
-
- switch (state)
+ get => showDragStretch;
+ set
{
- case FormWindowState.Minimized:
- WindowState = FormWindowState.Minimized;
- base.WindowState = FormWindowState.Minimized;
- break;
- case FormWindowState.Maximized:
- base.WindowState = FormWindowState.Normal;
- WindowState = FormWindowState.Normal;
- ShowMaximize();
- break;
- case FormWindowState.Normal:
- base.WindowState = FormWindowState.Normal;
- WindowState = FormWindowState.Maximized;
- ShowMaximize();
- break;
+ showDragStretch = value;
+ if (value)
+ {
+ ShowRect = true;
+ ShowRadius = false;
+ Padding = new Padding(2, showTitle ? TitleHeight : 2, 2, 2);
+ }
}
}
+
+ #region 拉拽调整窗体大小
+ const int WM_LEFT = 10;
+ const int WM_RIGHT = 11;
+ const int WM_TOP = 12;
+ const int WM_TOPLEFT = 13;
+ const int WM_TOPRIGHT = 14;
+ const int WM_BOTTOM = 15;
+ const int WM_BOTTOMLEFT = 0x10;
+ const int WM_BOTTOMRIGHT = 17;
+ protected override void WndProc(ref Message m)
+ {
+ base.WndProc(ref m);
+
+ if (ShowDragStretch && WindowState == FormWindowState.Normal && m.Msg == 0x0084)
+ {
+ Point vPoint = new Point((int)m.LParam & 0xFFFF, (int)m.LParam >> 16 & 0xFFFF);
+ vPoint = PointToClient(vPoint);
+ int dragSize = 5;
+ if (vPoint.X <= dragSize)
+ {
+ if (vPoint.Y <= dragSize)
+ m.Result = (IntPtr)WM_TOPLEFT;
+ else if (vPoint.Y >= ClientSize.Height - dragSize)
+ m.Result = (IntPtr)WM_BOTTOMLEFT;
+ else m.Result = (IntPtr)WM_LEFT;
+ }
+ else if (vPoint.X >= ClientSize.Width - dragSize)
+ {
+ if (vPoint.Y <= dragSize)
+ m.Result = (IntPtr)WM_TOPRIGHT;
+ else if (vPoint.Y >= ClientSize.Height - dragSize)
+ m.Result = (IntPtr)WM_BOTTOMRIGHT;
+ else m.Result = (IntPtr)WM_RIGHT;
+ }
+ else if (vPoint.Y <= dragSize)
+ {
+ m.Result = (IntPtr)WM_TOP;
+ }
+ else if (vPoint.Y >= ClientSize.Height - dragSize)
+ {
+ m.Result = (IntPtr)WM_BOTTOM;
+ }
+ }
+ }
+ #endregion
}
}
\ No newline at end of file
diff --git a/SunnyUI/Properties/AssemblyInfo.cs b/SunnyUI/Properties/AssemblyInfo.cs
index 8a8c88be..1f58c385 100644
--- a/SunnyUI/Properties/AssemblyInfo.cs
+++ b/SunnyUI/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.2.7.0")]
-[assembly: AssemblyFileVersion("2.2.7.0")]
\ No newline at end of file
+[assembly: AssemblyVersion("2.2.8.0")]
+[assembly: AssemblyFileVersion("2.2.8.0")]
\ No newline at end of file
diff --git a/SunnyUI/SunnyUI.csproj b/SunnyUI/SunnyUI.csproj
index bd9e55e0..cbf916cb 100644
--- a/SunnyUI/SunnyUI.csproj
+++ b/SunnyUI/SunnyUI.csproj
@@ -411,6 +411,7 @@
+
Component
diff --git a/SunnyUI/Units/USuspendCtrlAltDel.cs b/SunnyUI/Units/USuspendCtrlAltDel.cs
new file mode 100644
index 00000000..74a80078
--- /dev/null
+++ b/SunnyUI/Units/USuspendCtrlAltDel.cs
@@ -0,0 +1,180 @@
+/******************************************************************************
+ * SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。
+ * CopyRight (C) 2012-2020 ShenYongHua(沈永华).
+ * QQ群:56829229 QQ:17612584 EMail:SunnyUI@qq.com
+ *
+ * Blog: https://www.cnblogs.com/yhuse
+ * Gitee: https://gitee.com/yhuse/SunnyUI
+ * GitHub: https://github.com/yhuse/SunnyUI
+ *
+ * SunnyUI.dll can be used for free under the GPL-3.0 license.
+ * If you use this code, please keep this note.
+ * 如果您使用此代码,请保留此说明。
+ ******************************************************************************
+ * 文件名称: USuspendCtrlAltDel.cs
+ * 文件说明: 通过挂起winlogon线程来屏蔽Ctrl+Alt+Delete
+ * 当前版本: V2.2
+ * 创建日期: 2020-01-01
+ *
+ * 2020-09-17: V2.2.7 增加文件说明
+******************************************************************************/
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Sunny.UI
+{
+ ///
+ /// 通过挂起winlogon.exe线程来屏蔽Ctrl+Alt+Delete
+ /// 程序需要管理员权限
+ /// 需要提升进程权限为SE_PRIVILEGE_ENABLED权限
+ /// winlogon管理着开关机登录界面等功能
+ /// 调用Suspend挂起winlogon.exe,用完后需要Resume,否则无法调用关机界面
+ ///
+ public static class SuspendCtrlAltDelete
+ {
+ public static void GetSeDebugPrivilege()
+ {
+ IntPtr hToken;
+ LUID luidSEDebugNameValue = new LUID();
+
+
+ if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
+ {
+ Console.WriteLine("OpenProcessToken() failed, error = {0} . SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
+ return;
+ }
+ else
+ {
+ Console.WriteLine("OpenProcessToken() successfully");
+ }
+
+ if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, ref luidSEDebugNameValue))
+ {
+ Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
+ CloseHandle(hToken);
+ return;
+ }
+ else
+ {
+ Console.WriteLine("LookupPrivilegeValue() successfully");
+ }
+
+ TOKEN_PRIVILEGES tkpPrivileges = new TOKEN_PRIVILEGES();
+ tkpPrivileges.PrivilegeCount = 1;
+ tkpPrivileges.Privilege.Luid = luidSEDebugNameValue;
+ tkpPrivileges.Privilege.Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, 0))
+ {
+ Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
+ }
+ else
+ {
+ Console.WriteLine("SeDebugPrivilege is now available");
+ }
+ CloseHandle(hToken);
+ Console.ReadLine();
+ }
+
+ public static void Suspend()
+ {
+ Process[] processes = Process.GetProcesses();
+ foreach (Process process in processes)
+ {
+ if (process.ProcessName == "winlogon")
+ {
+
+ IntPtr p = OpenThread(PROCESS_ALL_ACCESS, false, (IntPtr)process.Threads[0].Id);
+ SuspendThread(p);
+ CloseHandle(p);
+ }
+ }
+ }
+
+ public static void Resume()
+ {
+ Process[] processes = Process.GetProcesses();
+ foreach (Process process in processes)
+ {
+ if (process.ProcessName == "winlogon")
+ {
+ IntPtr p = OpenThread(PROCESS_ALL_ACCESS, false, (IntPtr)process.Threads[0].Id);
+ ResumeThread(p);
+ CloseHandle(p);
+ }
+ }
+ }
+
+ const int PROCESS_ALL_ACCESS = 0x001F03FF;
+ const string SE_DEBUG_NAME = "SeDebugPrivilege";
+ const uint SE_PRIVILEGE_ENABLED = 0x00000002;
+ const uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
+ const uint STANDARD_RIGHTS_READ = 0x00020000;
+ const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
+ const uint TOKEN_DUPLICATE = 0x0002;
+ const uint TOKEN_IMPERSONATE = 0x0004;
+ const uint TOKEN_QUERY = 0x0008;
+ const uint TOKEN_QUERY_SOURCE = 0x0010;
+ const uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
+ const uint TOKEN_ADJUST_GROUPS = 0x0040;
+ const uint TOKEN_ADJUST_DEFAULT = 0x0080;
+ const uint TOKEN_ADJUST_SESSIONID = 0x0100;
+ const uint TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY;
+ const uint TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
+ TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
+ TOKEN_ADJUST_SESSIONID);
+
+
+ [DllImport("kernel32.dll")]
+ private static extern IntPtr OpenThread(int dwDesiredAccess, bool bInheritHandle, IntPtr dwThreadId);
+
+ [DllImport("kernel32.dll")]
+ private static extern bool CloseHandle(IntPtr hObject);
+
+ [DllImport("kernel32")]
+ private static extern int SuspendThread(IntPtr hThread);
+
+ [DllImport("kernel32")]
+ private static extern int ResumeThread(IntPtr hThread);
+
+ [DllImport("advapi32.dll", SetLastError = true)]
+ private static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);
+
+ [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
+ [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
+
+ [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
+ [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges,
+ [MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES NewState,
+ uint BufferLength, IntPtr PreviousState, uint ReturnLength);
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ private struct LUID
+ {
+ internal int LowPart;
+ internal uint HighPart;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ private struct TOKEN_PRIVILEGES
+ {
+ internal int PrivilegeCount;
+ internal LUID_AND_ATTRIBUTES Privilege;
+ }
+
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ private struct LUID_AND_ATTRIBUTES
+ {
+ internal LUID Luid;
+ internal uint Attributes;
+ }
+ }
+}