RaUI/Source/ryControls/Gdu.WinFormUI/Forms/GMForm.cs

1689 lines
52 KiB
C#
Raw Normal View History

/*
*
* 使
* 使ping3108@163.com,
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MGdu.WinFormUI;
using MGdu.WinFormUI.MyGraphics;
using System.Security.Permissions;
namespace MGdu.WinFormUI
{
/// <summary>
/// a form that supports custom theme
/// </summary>
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class GMForm : Form
{
#region private variable
ControlBoxManager controlBoxManager;
GMShadow _shawdowForm;
Form _lastClosedMdiChild;
List<Form> _listClosedMdiChild;
MdiBarController _mdiBarController;
#endregion
#region mdi event support
EventHandler _mdiNewTabButtonClick;
EventHandler _mdiTabCloseButtonClick;
EventHandler _mdiBarCreated;
/// <summary>
/// 标签新建按钮事件
/// </summary>
[Description("标签新建按钮事件")]
public event EventHandler MdiNewTabButtonClick
{
add
{
_mdiNewTabButtonClick = value;
}
remove
{
_mdiNewTabButtonClick = null;
}
}
/// <summary>
/// 标签关闭按钮事件
/// </summary>
[Description("标签关闭按钮事件")]
public event EventHandler MdiTabCloseButtonClick
{
add
{
_mdiTabCloseButtonClick = value;
}
remove
{
_mdiTabCloseButtonClick = null;
}
}
/// <summary>
///标签创建时事件
/// </summary>
[Description("标签创建时事件")]
public event EventHandler MdiBarCreated
{
add { _mdiBarCreated = value; }
remove { _mdiBarCreated = null; }
}
private void OnMdiNewTabButtonClick(object sender, EventArgs e)
{
_mdiNewTabButtonClick?.Invoke(sender, e);
}
private void OnMdiTabCloseButtonClick(object sender, EventArgs e)
{
_mdiTabCloseButtonClick?.Invoke(sender, e);
}
/// <summary>
/// 在标签栏创建时激发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnMdiBarCreated(object sender, EventArgs e)
{
_mdiBarCreated?.Invoke(sender, e);
}
#endregion
#region property
#region property private var
bool _resizable = true; // not with theme
Padding _padding = new Padding(0); // not with theme
ThemeFormBase _myTheme;
#endregion
/// <summary>
/// 内边距
/// </summary>
[DefaultValue(typeof(Padding), "0")]
public new Padding Padding
{
get { return _padding; }
set
{
_padding = value;
base.Padding = new Padding(
BorderWidth + _padding.Left,
CaptionHeight + BorderWidth + _padding.Top,
BorderWidth + _padding.Right,
BorderWidth + _padding.Bottom);
}
}
/// <summary>
/// 默认内边距
/// </summary>
protected override Padding DefaultPadding
{
get
{
return new Padding(
BorderWidth,
BorderWidth + CaptionHeight,
BorderWidth,
BorderWidth);
}
}
/// <summary>
/// 标题
/// </summary>
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
Invalidate(TextRect);
}
}
/// <summary>
/// 皮肤/主题
/// </summary>
[Browsable(false)]
public ThemeFormBase XTheme
{
get
{
if (_myTheme == null)
_myTheme = new ThemeFormBase();
return _myTheme;
}
set
{
_myTheme = value;
PrepareForNewTheme();
Invalidate();
}
}
#region editable gmform properties
/// <summary>
/// 是否可拖动改变窗体大小
/// </summary>
[Category("GMForm")]
[Description("是否可拖动改变窗体大小")]
[DefaultValue(true)]
public bool Resizable
{
get { return _resizable; }
set
{
_resizable = value;
}
}
/// <summary>
/// 窗体边界大小,鼠标移动到该边界将变成指针形状,拖动可改变窗体大小
/// </summary>
[Category("GMForm")]
[Description("窗体边界大小,鼠标移动到该边界将变成指针形状,拖动可改变窗体大小")]
[DefaultValue(6)]
public int SideResizeWidth
{
get { return XTheme.SideResizeWidth; }
set
{
if (value != XTheme.SideResizeWidth)
{
XTheme.SideResizeWidth = value;
}
}
}
/// <summary>
/// 窗体边框大小
/// </summary>
[Category("GMForm")]
[Description("窗体边框大小")]
[DefaultValue(6)]
public int BorderWidth
{
get { return XTheme.BorderWidth; }
set
{
if (value != XTheme.BorderWidth)
{
XTheme.BorderWidth = value;
Invalidate();
}
}
}
/// <summary>
/// 标题栏高度
/// </summary>
[Category("GMForm")]
[Description("标题栏高度")]
[DefaultValue(30)]
public int CaptionHeight
{
get { return XTheme.CaptionHeight; }
set
{
if (value != XTheme.CaptionHeight)
{
XTheme.CaptionHeight = value;
Invalidate();
}
}
}
/// <summary>
///窗体圆角程度
/// </summary>
[Category("GMForm")]
[DefaultValue(8)]
[Description("窗体圆角程度")]
public int Radius
{
get { return XTheme.Radius; }
set
{
if (value != XTheme.Radius)
{
XTheme.Radius = (value < 0 ? 0 : value);
Invalidate();
}
}
}
/// <summary>
/// 窗体圆角样式
/// </summary>
[Category("GMForm")]
[DefaultValue(typeof(RoundStyle), "2")]
[Description("窗体圆角样式")]
public RoundStyle Round
{
get { return XTheme.RoundedStyle; }
set
{
if (value != XTheme.RoundedStyle)
{
XTheme.RoundedStyle = value;
Invalidate();
}
}
}
/// <summary>
/// 控制按钮相对于右上角的偏移量
/// </summary>
[Category("GMForm")]
[Description("控制按钮相对于右上角的偏移量")]
[DefaultValue(typeof(Point), "8, 8")]
public Point ControlBoxOffset
{
get { return XTheme.ControlBoxOffset; }
set
{
XTheme.ControlBoxOffset = value;
Invalidate();
}
}
/// <summary>
/// 关闭/最大化/最小化按钮之间的距离,可以设置成负值使它们重叠
/// </summary>
[Category("GMForm")]
[Description("关闭/最大化/最小化按钮之间的距离,可以设置成负值使它们重叠")]
[DefaultValue(0)]
public int ControlBoxSpace
{
get { return XTheme.ControlBoxSpace; }
set
{
XTheme.ControlBoxSpace = value;
Invalidate();
}
}
/// <summary>
/// 标题栏图标尺寸
/// </summary>
[Category("GMForm")]
[Description("标题栏图标尺寸")]
[DefaultValue(typeof(Size), "16,16")]
public Size IconSize
{
get
{
if (ShowIcon)
return XTheme.IconSize;
else
return System.Drawing.Size.Empty;
}
set
{
XTheme.IconSize = value;
Invalidate();
}
}
/// <summary>
/// 标题栏图标与窗体左边框的距离
/// </summary>
[Category("GMForm")]
[Description("标题栏图标与窗体左边框的距离")]
[DefaultValue(2)]
public int IconLeftMargin
{
get { return (this.ShowIcon ? XTheme.IconLeftMargin : 0); }
set
{
XTheme.IconLeftMargin = value;
Invalidate();
}
}
/// <summary>
/// 标题距离左边的距离
/// </summary>
[Category("GMForm")]
[DefaultValue(2), Description("标题距离左边的距离")]
public int TextLeftMargin
{
get { return XTheme.TextLeftMargin; }
set
{
XTheme.TextLeftMargin = value;
Invalidate();
}
}
/// <summary>
/// 窗体关闭按钮的尺寸
/// </summary>
[Category("GMForm")]
[Description("窗体关闭按钮的尺寸")]
[DefaultValue(typeof(Size), "37, 17")]
public Size CloseBoxSize
{
get { return XTheme.CloseBoxSize; }
set
{
XTheme.CloseBoxSize = value;
Invalidate();
}
}
/// <summary>
/// 窗体最大化/还原按钮的大小
/// </summary>
[Category("GMForm")]
[DefaultValue(typeof(Size), "25, 17")]
[Description("窗体最大化/还原按钮的大小")]
public Size MaxBoxSize
{
get { return XTheme.MaxBoxSize; }
set
{
XTheme.MaxBoxSize = value;
Invalidate();
}
}
/// <summary>
/// 窗体最小化按钮的大小
/// </summary>
[Category("GMForm")]
[DefaultValue(typeof(Size), "25, 17")]
[Description("窗体最小化按钮的大小")]
public Size MinBoxSize
{
get { return XTheme.MinBoxSize; }
set
{
XTheme.MinBoxSize = value;
Invalidate();
}
}
#endregion
#region form shadow about
/// <summary>
/// 是否显示阴影
/// </summary>
[Category("Form Shadow"), Description("是否显示阴影")]
public bool ShowShadow
{
get { return XTheme.ShowShadow; }
set
{
if (value != XTheme.ShowShadow)
{
XTheme.ShowShadow = value;
}
}
}
/// <summary>
/// 窗体阴影宽度
/// </summary>
[Category("Form Shadow"), Description("窗体阴影宽度")]
public int ShadowWidth
{
get { return XTheme.ShadowWidth; }
set
{
XTheme.ShadowWidth = value;
}
}
/// <summary>
/// 使用阴影来缩放
/// </summary>
[Category("Form Shadow"), Description("使用阴影来缩放")]
public bool UseShadowToResize
{
get { return XTheme.UseShadowToResize; }
set
{
XTheme.UseShadowToResize = value;
}
}
/// <summary>
/// 窗体阴影颜色
/// </summary>
[Category("Form Shadow")]
[Description("窗体阴影颜色")]
public Color ShadowColor
{
get { return XTheme.ShadowColor; }
set
{
XTheme.ShadowColor = value;
}
}
/// <summary>
/// 阴影从里到外是逐渐变浅的这个值设置深色部分的透明度ARGB中的A值
/// </summary>
[Category("Form Shadow")]
[Description("阴影从里到外是逐渐变浅的这个值设置深色部分的透明度ARGB中的A值")]
public int ShadowAValueDark
{
get { return XTheme.ShadowAValueDark; }
set
{
XTheme.ShadowAValueDark = value;
}
}
/// <summary>
/// 阴影从里到外是逐渐变浅的这个值设置浅色部分的透明度ARGB中的A值
/// </summary>
[Category("Form Shadow")]
[Description("阴影从里到外是逐渐变浅的这个值设置浅色部分的透明度ARGB中的A值")]
public int ShadowAValueLight
{
get { return XTheme.ShadowAValueLight; }
set
{
XTheme.ShadowAValueLight = value;
}
}
#endregion
#region form resize region, internal readonly
internal Rectangle TopLeftRect
{
get
{
return new Rectangle(0, 0, SideResizeWidth, SideResizeWidth);
}
}
internal Rectangle TopRect
{
get
{
return new Rectangle(
SideResizeWidth,
0,
this.Size.Width - SideResizeWidth * 2,
SideResizeWidth);
}
}
internal Rectangle TopRightRect
{
get
{
return new Rectangle(
this.Size.Width - SideResizeWidth,
0,
SideResizeWidth,
SideResizeWidth);
}
}
internal Rectangle LeftRect
{
get
{
return new Rectangle(
0,
SideResizeWidth,
SideResizeWidth,
this.Size.Height - SideResizeWidth * 2);
}
}
internal Rectangle RightRect
{
get
{
return new Rectangle(
this.Size.Width - SideResizeWidth,
SideResizeWidth,
SideResizeWidth,
this.Size.Height - SideResizeWidth * 2);
}
}
internal Rectangle BottomLeftRect
{
get
{
return new Rectangle(
0,
this.Size.Height - SideResizeWidth,
SideResizeWidth,
SideResizeWidth);
}
}
internal Rectangle BottomRect
{
get
{
return new Rectangle(
SideResizeWidth,
this.Size.Height - SideResizeWidth,
this.Size.Width - SideResizeWidth * 2,
SideResizeWidth);
}
}
internal Rectangle BottomRightRect
{
get
{
return new Rectangle(
this.Size.Width - SideResizeWidth,
this.Size.Height - SideResizeWidth,
SideResizeWidth,
SideResizeWidth);
}
}
#endregion
#region calculated rect
internal Rectangle CaptionRect
{
get
{
return new Rectangle(
BorderWidth,
BorderWidth,
this.ClientSize.Width - BorderWidth * 2,
CaptionHeight);
}
}
internal Rectangle CaptionRectToDraw
{
get
{
return new Rectangle(
0,
0,
this.ClientSize.Width,
CaptionHeight + BorderWidth);
}
}
internal Rectangle CloseBoxRect
{
get
{
if (ControlBox)
{
int x = ClientSize.Width - ControlBoxOffset.X - CloseBoxSize.Width;
return new Rectangle(
new Point(x, ControlBoxOffset.Y),
CloseBoxSize);
}
else
return Rectangle.Empty;
}
}
internal Rectangle MaxBoxRect
{
get
{
if (ControlBox && MaximizeBox)
{
int x = CloseBoxRect.Left - ControlBoxSpace - MaxBoxSize.Width;
return new Rectangle(
new Point(x, ControlBoxOffset.Y),
MaxBoxSize);
}
else
return Rectangle.Empty;
}
}
internal Rectangle MinBoxRect
{
get
{
if (ControlBox && MinimizeBox)
{
int x;
if (MaximizeBox)
x = MaxBoxRect.Left - ControlBoxSpace - MinBoxSize.Width;
else
x = CloseBoxRect.Left - ControlBoxSpace - MinBoxSize.Width;
return new Rectangle(
new Point(x, ControlBoxOffset.Y),
MinBoxSize);
}
else
return Rectangle.Empty;
}
}
internal Rectangle IconRect
{
get
{
if (ControlBox && ShowIcon)
{
int x = BorderWidth + IconLeftMargin;
int y = BorderWidth + (CaptionHeight - IconSize.Height) / 2;
return new Rectangle(new Point(x, y), IconSize);
}
else
return new Rectangle(BorderWidth, BorderWidth, 0, 0);
}
}
internal Rectangle TextRect
{
get
{
int x = IconRect.Right + TextLeftMargin;
int y = BorderWidth;
int height = CaptionHeight;
int right = this.ClientSize.Width - x;
if (ControlBox)
{
right = CloseBoxRect.Left;
if (MinimizeBox)
{
right = MinBoxRect.Left;
}
else if (MaximizeBox)
{
right = MaxBoxRect.Left;
}
}
int width = right - x;
return new Rectangle(x, y, width, height);
}
}
#endregion
/// <summary>
/// 表示去掉自画的边框及标题栏后,剩下的可用的客户区区域,坐标相对于窗体左上角
/// </summary>
[Browsable(false)]
public Rectangle UserClientBounds
{
get
{
return new Rectangle(
BorderWidth,
BorderWidth + CaptionHeight,
ClientSize.Width - BorderWidth * 2,
ClientSize.Height - BorderWidth * 2 - CaptionHeight);
}
}
/// <summary>
/// 表示去掉自画的边框及标题栏后,剩下的可用的客户区大小
/// </summary>
[Browsable(false)]
public Size UserClientSize
{
get
{
return new Size(
ClientSize.Width - BorderWidth * 2,
ClientSize.Height - BorderWidth * 2 - CaptionHeight);
}
}
/// <summary>
/// 表示MDI标签栏的区域包括bottom-region
/// </summary>
[Browsable(false)]
public Rectangle MdiBarBounds
{
get
{
if (!IsMdiContainer || _mdiBarController == null)
return Rectangle.Empty;
return _mdiBarController.Bounds;
}
}
#endregion
#region constructor & initialize
/// <summary>
/// MGdUI皮肤
/// </summary>
public GMForm()
: base()
{
InitializeComponent();
FormIni();
//if (!DesignMode)
//{
// base.ShowInTaskbar = ShowInTaskbar;
//}
// 下面这个条件是永远不为true的如果不把此类直接设置成mdicontainer
//if (this.IsMdiContainer)
// SetMdiClient();
}
private void FormIni()
{
this.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw, true);
this.DoubleBuffered = true;
this.UpdateStyles();
base.Padding = DefaultPadding;
if (ControlBox)
controlBoxManager = new ControlBoxManager(this);
}
#region MDI-Support
/// <summary>
/// 获取子窗体
/// </summary>
/// <returns></returns>
public MdiClient GetMdiClient()
{
MdiClient mdiclient = null;
foreach (Control ctl in Controls)
{
if ((mdiclient = ctl as MdiClient) != null)
break;
}
return mdiclient;
}
/// <summary>
/// 通过sendmessage方式激活子窗体以避免闪烁
/// </summary>
/// <param name="childToActivate"></param>
public void ActivateMdiChildForm(Form childToActivate)
{
MdiClient mdi = GetMdiClient();
if (mdi == null)
return;
if (base.ActiveMdiChild == childToActivate)
return;
if (base.MdiChildren.Length < 2)
return;
Control form = null;
bool isNext = false;
int pos = mdi.Controls.IndexOf(childToActivate);
if (pos < 0)
return;
if (pos == 0)
{
form = mdi.Controls[pos + 1];
isNext = true;
}
else
{
form = mdi.Controls[pos - 1];
isNext = false;
}
IntPtr next = (isNext ? Win32.WinAPI.TRUE : Win32.WinAPI.FALSE);
Win32.WinAPI.SendMessage(mdi.Handle,
(int)Win32.WinAPI.WindowMessages.WM_MDINEXT, form.Handle, next);
}
private void SetMdiClient()
{
if (!IsMdiContainer)
return;
MdiClient mdi = GetMdiClient();
if (mdi != null)
{
SetMdiStyles(mdi);
UpdateMdiStyles(mdi);
SetMdiClientLocation(mdi);
}
}
private void SetMdiStyles(MdiClient mdi)
{
// remove the border
int style = Win32.WinAPI.GetWindowLong(mdi.Handle, (int)Win32.WinAPI.GWLPara.GWL_STYLE);
int exStyle = Win32.WinAPI.GetWindowLong(mdi.Handle, (int)Win32.WinAPI.GWLPara.GWL_EXSTYLE);
style &= ~(int)Win32.WinAPI.WindowStyle.WS_BORDER;
exStyle &= ~(int)Win32.WinAPI.WindowStyleEx.WS_EX_CLIENTEDGE;
Win32.WinAPI.SetWindowLong(mdi.Handle, (int)Win32.WinAPI.GWLPara.GWL_STYLE, style);
Win32.WinAPI.SetWindowLong(mdi.Handle, (int)Win32.WinAPI.GWLPara.GWL_EXSTYLE, exStyle);
Win32.WinAPI.ShowScrollBar(mdi.Handle, (int)Win32.WinAPI.ScrollBar.SB_BOTH, 0 /*false*/);
}
private void UpdateMdiStyles(MdiClient mdi)
{
// To show style changes, the non-client area must be repainted. Using the
// control's Invalidate method does not affect the non-client area.
// Instead use a Win32 call to signal the style has changed.
Win32.WinAPI.SetWindowPos(mdi.Handle, IntPtr.Zero, 0, 0, 0, 0,
(uint)Win32.WinAPI.SWPPara.SWP_NOACTIVATE |
(uint)Win32.WinAPI.SWPPara.SWP_NOMOVE |
(uint)Win32.WinAPI.SWPPara.SWP_NOSIZE |
(uint)Win32.WinAPI.SWPPara.SWP_NOZORDER |
(uint)Win32.WinAPI.SWPPara.SWP_NOOWNERZORDER |
(uint)Win32.WinAPI.SWPPara.SWP_FRAMECHANGED);
}
private void SetMdiClientLocation(MdiClient mdi)
{
mdi.BackColor = Color.White;
//mdi.Margin = new Padding(10);
//mdi.Dock = DockStyle.None;
//mdi.Location = new Point(30, 40);
//mdi.Size = new Size(400, 260);
}
// used for child mdi form to notify its parent form that it's closed
/// <summary>
/// 当子窗体关闭时激发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void MdiChildClosed(object sender, FormClosedEventArgs e)
{
Form child = sender as Form;
if (child != null)
{
_lastClosedMdiChild = child;
_listClosedMdiChild.Add(child);
}
}
// for mdi child form
/// <summary>
/// 子窗体可视化变化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void MdiChildVisibleChange(object sender, EventArgs e)
{
base.Invalidate();
}
/// <summary>
/// 获取当前的子窗体列表
/// </summary>
/// <returns></returns>
public List<Form> GetCurrentMdiChildren()
{
List<Form> list = new List<Form>();
if (_listClosedMdiChild != null)
{
foreach (Form f in MdiChildren)
{
if (!_listClosedMdiChild.Contains(f) && f.Visible)
list.Add(f);
}
}
return list;
}
#endregion
#endregion
#region private method
private void SetFormMinimizeSize()
{
int minW = 160;
int minH = 60;
int w = BorderWidth * 2 + IconLeftMargin + IconSize.Width
+ TextLeftMargin + MinBoxSize.Width + MaxBoxSize.Width
+ CloseBoxSize.Width + ControlBoxSpace * 2
+ ControlBoxOffset.X + 12;
if (w < minW)
w = minW;
int h = BorderWidth * 2 + CaptionHeight + 8;
if (h < minH)
h = minH;
base.MinimumSize = new Size(w, h);
}
private void SetShadowFormSize()
{
if (_shawdowForm == null || _shawdowForm.IsDisposed)
return;
if (base.WindowState == FormWindowState.Normal)
{
var size = base.Size;
if (!this.DesignMode)
{
size.Width += XTheme.ShadowWidth * 2;
size.Height += XTheme.ShadowWidth * 2;
}
if (_shawdowForm.Size != size)
{
_shawdowForm.Size = size;
// update size -- api: movewindow....
}
}
}
private void SetShadowFormLocation()
{
if (_shawdowForm == null || _shawdowForm.IsDisposed)
return;
if (base.WindowState == FormWindowState.Normal)
{
Point p = base.Location;
if (!this.DesignMode)
{ p.Offset(-XTheme.ShadowWidth, -XTheme.ShadowWidth); }
if (_shawdowForm.Location != p)
{
_shawdowForm.Location = p;
// update location -- api: movewindow....
}
}
}
private void PrepareForNewTheme()
{
if (base.Region != null)
base.Region.Dispose();
base.Region = null;
if (ControlBox)
{
controlBoxManager.ResetBoxColor();
controlBoxManager.FormResize();
}
SetFormRegion();
//Padding = new Padding(0);
base.BackColor = XTheme.FormBackColor;
base.OnSizeChanged(EventArgs.Empty);
SetFormMinimizeSize();
if (XTheme.ShowShadow)
{
if (_shawdowForm == null || _shawdowForm.IsDisposed)
{
OnActivated(EventArgs.Empty);
}
}
else
{
if (_shawdowForm != null)
{
_shawdowForm.Close();
_shawdowForm = null;
}
}
}
private void SetFormRegion()
{
if (this.DesignMode) { return; }
if (base.Region != null)
base.Region.Dispose();
Rectangle rect = new Rectangle(Point.Empty, base.Size);
GraphicsPath path;
if (XTheme.UseDefaultTopRoundingFormRegion)
path = GraphicsPathHelper.CreateTopRoundedPathForFormRegion(rect);
else
path = GraphicsPathHelper.CreateRoundedRect(rect, Radius, Round, false);
this.Region = new Region(path);
}
//private GraphicsPath CreateRoundedFormRect(bool correction)
//{
// Rectangle rect = new Rectangle(Point.Empty, this.Size);
// return GraphicsPathHelper.CreateRoundedRect(rect, Radius, Round, correction);
//}
/// <summary>
/// 判断所接收到的 wm_nc-calc-size 消息是否指示窗体即将最小化
/// </summary>
private bool IsAboutToMinimize(Win32.WinAPI.RECT rect)
{
if (rect.Left == -32000 && rect.Top == -32000)
return true;
else
return false;
}
/// <summary>
/// 判断所接收到的 wm_nc-calc-size 消息是否指示窗体即将最大化
/// </summary>
private bool IsAboutToMaximize(Win32.WinAPI.RECT rect)
{
/*
*
*
*/
int left = rect.Left;
int top = rect.Top;
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
if (left < 0 && top < 0)
{
Rectangle workingArea = Screen.GetWorkingArea(this);
if (width == (workingArea.Width + (-left) * 2)
&& height == (workingArea.Height + (-top) * 2))
return true;
}
return false;
}
private void DrawFormBackground(Graphics g)
{
SmoothingMode oldMode = g.SmoothingMode;
if (Round != RoundStyle.None)
g.SmoothingMode = SmoothingMode.AntiAlias;
using (SolidBrush sb = new SolidBrush(XTheme.FormBackColor))
{
using (GraphicsPath path = GraphicsPathHelper.CreateRoundedRect(
ClientRectangle, Radius, Round, false))
{
g.FillPath(sb, path);
}
}
g.SmoothingMode = oldMode;
}
private void DrawCaptionBackground(Graphics g)
{
using (LinearGradientBrush lb = new LinearGradientBrush(
CaptionRectToDraw,
XTheme.CaptionBackColorTop,
XTheme.CaptionBackColorBottom,
LinearGradientMode.Vertical))
{
g.FillRectangle(lb, CaptionRectToDraw);
}
}
private void DrawFormIconAndText(Graphics g)
{
if (ShowIcon && Icon != null && XTheme.DrawCaptionIcon)
{
g.DrawIcon(this.Icon, IconRect);
}
if (!string.IsNullOrEmpty(Text) && XTheme.DrawCaptionText)
{
TextRenderer.DrawText(
g,
this.Text,
SystemFonts.CaptionFont,
TextRect,
XTheme.CaptionTextColor,
(XTheme.CaptionTextCenter ? TextFormatFlags.HorizontalCenter : TextFormatFlags.Left) |
TextFormatFlags.VerticalCenter |
TextFormatFlags.EndEllipsis);
}
}
private void DrawFormBorder(Graphics g)
{
if (this.DesignMode) { return; }
int width = BorderWidth;
Rectangle rect = ClientRectangle;
SmoothingMode oldMode = g.SmoothingMode;
if (Round != RoundStyle.None)
g.SmoothingMode = SmoothingMode.AntiAlias;
// outter border
if (width > 0)
{
using (Pen p = new Pen(XTheme.FormBorderOutterColor))
{
using (GraphicsPath path = GraphicsPathHelper.CreateRoundedRect(
rect, Radius, Round, true))
{
g.DrawPath(p, path);
}
}
}
width--;
// inner border
if (width > 0)
{
using (Pen p = new Pen(XTheme.FormBorderInnerColor))
{
rect.Inflate(-1, -1);
using (GraphicsPath path = GraphicsPathHelper.CreateRoundedRect(
rect, Radius, Round, true))
{
g.DrawPath(p, path);
}
}
}
width--;
g.SmoothingMode = oldMode;
// other inside border
using (Pen p = new Pen(XTheme.FormBorderInmostColor))
{
while (width > 0)
{
rect.Inflate(-1, -1);
g.DrawRectangle(p, rect);
width--;
}
}
}
/// <summary>
/// to make the client area to have 3D view
/// </summary>
private void DrawInsetClientRect(Graphics g)
{
if (this.DesignMode) { return; }
int x = BorderWidth;
int y = BorderWidth + CaptionHeight;
int w = ClientSize.Width - BorderWidth * 2;
int h = ClientSize.Height - BorderWidth * 2 - CaptionHeight;
Rectangle clientRect = new Rectangle(x, y, w, h);
clientRect.Width--;
clientRect.Height--;
Color inner = ColorHelper.GetDarkerColor(this.BackColor, 20);
clientRect.Inflate(1, 1);
using (Pen p1 = new Pen(inner))
{
g.DrawRectangle(p1, clientRect);
}
Color outter = Color.FromArgb(80, 255, 255, 255);
clientRect.Inflate(1, 1);
using (Pen p2 = new Pen(outter))
{
g.DrawRectangle(p2, clientRect);
}
}
#endregion
#region your Win-Message handler method
private bool WmNcActivate(ref Message m)
{
// something here
m.Result = Win32.WinAPI.TRUE;
return true;
}
private bool WmNcCalcSize(ref Message m)
{
if (m.WParam == new IntPtr(1))
{
Win32.WinAPI.NCCALCSIZE_PARAMS info = (Win32.WinAPI.NCCALCSIZE_PARAMS)
Marshal.PtrToStructure(m.LParam, typeof(Win32.WinAPI.NCCALCSIZE_PARAMS));
if (IsAboutToMaximize(info.rectNewForm))
{
Rectangle workingRect = Screen.GetWorkingArea(this);
info.rectNewForm.Left = workingRect.Left - BorderWidth;
info.rectNewForm.Top = workingRect.Top - BorderWidth;
info.rectNewForm.Right = workingRect.Right + BorderWidth;
info.rectNewForm.Bottom = workingRect.Bottom + BorderWidth;
Marshal.StructureToPtr(info, m.LParam, false);
}
}
return true;
}
private bool WmNcHitTest(ref Message m)
{
int para = m.LParam.ToInt32();
//var point = MousePosition;
//int x0 = Win32.WinAPI.LOWORD(para);
//int y0 = Win32.WinAPI.HIWORD(para);
Point p = PointToClient(MousePosition);
if (Resizable)
{
if (TopLeftRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTTOPLEFT);
return true;
}
if (TopRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTTOP);
return true;
}
if (TopRightRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTTOPRIGHT);
return true;
}
if (LeftRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTLEFT);
return true;
}
if (RightRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTRIGHT);
return true;
}
if (BottomLeftRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTBOTTOMLEFT);
return true;
}
if (BottomRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTBOTTOM);
return true;
}
if (BottomRightRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTBOTTOMRIGHT);
return true;
}
}
if (IconRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTSYSMENU);
return true;
}
if (CloseBoxRect.Contains(p) || MaxBoxRect.Contains(p) || MinBoxRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTCLIENT);
return true;
}
if (IsMdiContainer && _mdiBarController != null)
{
if (_mdiBarController.HitTestBounds.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTCLIENT);
return true;
}
}
if (CaptionRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTCAPTION);
return true;
}
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTCLIENT);
return true;
}
#endregion
#region override method
/// <summary>
/// 消息
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
if (this.DesignMode) { base.WndProc(ref m); return; }
bool alreadyHandled = false;
switch (m.Msg)
{
case (int)Win32.WinAPI.WindowMessages.WM_NCCALCSIZE:
alreadyHandled = WmNcCalcSize(ref m);
break;
case (int)Win32.WinAPI.WindowMessages.WM_NCHITTEST:
alreadyHandled = WmNcHitTest(ref m);
break;
case (int)Win32.WinAPI.WindowMessages.WM_NCACTIVATE:
alreadyHandled = WmNcActivate(ref m);
break;
case (int)Win32.WinAPI.WindowMessages.WM_NCPAINT:
alreadyHandled = true;
break;
default:
break;
}
if (!alreadyHandled)
base.WndProc(ref m);
}
/// <summary>
/// 画UI
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
DrawFormBackground(e.Graphics);
DrawCaptionBackground(e.Graphics);
DrawFormBorder(e.Graphics);
DrawFormIconAndText(e.Graphics);
if (XTheme.SetClientInset)
DrawInsetClientRect(e.Graphics);
if (ControlBox)
controlBoxManager.DrawBoxes(e.Graphics);
if (IsMdiContainer && _mdiBarController != null)
_mdiBarController.RenderTheBar(e.Graphics);
}
/// <summary>
/// 在画背景时激发
/// </summary>
/// <param name="e"></param>
protected override void OnPaintBackground(PaintEventArgs e)
{
//base.OnPaintBackground(e);
}
/// <summary>
/// 重写该方法解决窗体每次还原都会变大的问题
/// </summary>
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
if (this.DesignMode) { base.SetBoundsCore(x, y, width, height, specified); return; }
if (base.WindowState == FormWindowState.Normal)
{
if (this.Size == this.ClientSize)
{
//if (width == (this.Size.Width + SystemInformation.FrameBorderSize.Width * 2))
if (width == (this.Size.Width + 4 * 2) || width == (this.Size.Width + 8 * 2))
{
width = this.Size.Width;
height = this.Size.Height;
}
}
}
base.SetBoundsCore(x, y, width, height, specified);
}
/// <summary>
/// 重写该方法解决在VS设计器中每次保存一个新的尺寸再打开尺寸会变大的问题
/// </summary>
protected override void SetClientSizeCore(int x, int y)
{
//MessageBox.Show("before SetClientSizeCore,size:" +
// base.Size.ToString() + ", clisize:" + base.ClientSize.ToString()
// + ", x:" + x.ToString() + ", y:" + y.ToString());
//if (base.WindowState == FormWindowState.Normal && DesignMode)
//{
// if (base.Size != base.ClientSize)
// {
// int diffx = Size.Width - ClientSize.Width;
// int diffy = Size.Height - ClientSize.Height;
// if (diffx == 4 * 2 || diffx == 8 * 2)
// {
// x -= diffx;
// y -= diffy;
// }
// }
//}
base.SetClientSizeCore(x, y);
//MessageBox.Show(base.SizeFromClientSize(new Size(x,y)).ToString());
//MessageBox.Show("after SetClientSizeCore,size:" +
// base.Size.ToString() + ", clisize:" + base.ClientSize.ToString()
// + ", x:" + x.ToString() + ", y:" + y.ToString());
}
/// <summary>
/// 创建控件时激发
/// </summary>
protected override void OnCreateControl()
{
base.OnCreateControl();
SetFormRegion();
}
/// <summary>
/// 窗体可见变化时激发
/// </summary>
/// <param name="e"></param>
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (_shawdowForm != null)
_shawdowForm.Visible = base.Visible;
}
/// <summary>
/// 大小改变时激发
/// </summary>
/// <param name="e"></param>
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
SetFormRegion();
if (ControlBox)
controlBoxManager.FormResize();
if (XTheme.ShowShadow && _shawdowForm != null
&& !_shawdowForm.IsDisposed)
{
if (base.WindowState == FormWindowState.Normal)
{
_shawdowForm.Visible = true;
SetShadowFormSize();
}
else
{
_shawdowForm.Visible = false;
}
}
}
/// <summary>
/// 在位置变化时激发
/// </summary>
/// <param name="e"></param>
protected override void OnLocationChanged(EventArgs e)
{
base.OnLocationChanged(e);
if (XTheme.ShowShadow && _shawdowForm != null
&& !_shawdowForm.IsDisposed && _shawdowForm.Visible)
SetShadowFormLocation();
}
/// <summary>
/// 窗体激活
/// </summary>
/// <param name="e"></param>
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
if (XTheme.ShowShadow && !base.IsMdiChild)
{
if (_shawdowForm == null)
{
_shawdowForm = new GMShadow(this);
SetShadowFormSize();
SetShadowFormLocation();
_shawdowForm.Show(this);
SetShadowFormSize();
SetShadowFormLocation();
_shawdowForm.TopMost = base.TopMost;
var size = base.MinimumSize;
size.Width += ShadowWidth * 2;
size.Height += ShadowWidth * 2;
_shawdowForm.MinimumSize = size;
if (XTheme.UseShadowToResize)
_shawdowForm.BeginToResizeOwner();
}
}
}
/// <summary>
/// 窗体关闭后激发
/// </summary>
/// <param name="e"></param>
protected override void OnFormClosed(FormClosedEventArgs e)
{
if (_shawdowForm != null && !_shawdowForm.IsDisposed)
_shawdowForm.Close();
base.OnFormClosed(e);
}
/// <summary>
/// 加载时
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (base.IsMdiContainer)
{
SetMdiClient();
_listClosedMdiChild = new List<Form>();
_mdiBarController = new MdiBarController(this);
_mdiBarController.TabCloseButtonClick += new EventHandler(OnMdiTabCloseButtonClick);
_mdiBarController.NewTabButtonClick += new EventHandler(OnMdiNewTabButtonClick);
OnMdiBarCreated(this, EventArgs.Empty);
}
}
/// <summary>
/// 在子窗体激活时激发
/// </summary>
/// <param name="e"></param>
protected override void OnMdiChildActivate(EventArgs e)
{
base.OnMdiChildActivate(e);
Invalidate();
}
/// <summary>
/// 标签菜单
/// </summary>
public ContextMenuStrip TabContextMenuStrip { get; set; } = null;
/// <summary>
/// 窗体上移动鼠标时激发
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (ControlBox)
controlBoxManager.MouseOperation(e.Location, MouseOperationType.Move);
if (IsMdiContainer && _mdiBarController != null)
_mdiBarController.MouseOperation(e.Location, MouseOperationType.Move);
}
/// <summary>
/// 获取当前点击的标签项
/// </summary>
public Form ClickTab { get; set; } = null;
/// <summary>
/// 在窗体上按下鼠标时激发
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button != System.Windows.Forms.MouseButtons.Left)
{
return;
}
if (ControlBox)
controlBoxManager.MouseOperation(e.Location, MouseOperationType.Down);
if (IsMdiContainer && _mdiBarController != null)
_mdiBarController.MouseOperation(e.Location, MouseOperationType.Down);
}
/// <summary>
/// 在窗体上放开鼠标时激发
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button != System.Windows.Forms.MouseButtons.Left)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
if (TabContextMenuStrip != null)
{
foreach (MdiGMTabItem tab in _mdiBarController._listTabItems)
{
if (!tab.IsHidden)
{
if (tab.Bounds.Contains(e.Location) && !tab.CloseBtnRect.Contains(e.Location))
{
ClickTab = tab.Form;
TabContextMenuStrip.Show(PointToScreen(e.Location));
break;
}
}
}
}
}
return;
}
if (e.Clicks > 1)
return;
if (ControlBox)
controlBoxManager.MouseOperation(e.Location, MouseOperationType.Up);
if (IsMdiContainer && _mdiBarController != null)
_mdiBarController.MouseOperation(e.Location, MouseOperationType.Up);
}
/// <summary>
/// 在鼠标离开窗体时激发
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (ControlBox)
controlBoxManager.MouseOperation(Point.Empty, MouseOperationType.Leave);
if (IsMdiContainer && _mdiBarController != null)
_mdiBarController.MouseOperation(Point.Empty, MouseOperationType.Leave);
}
#endregion
}
}