2020-11-28 07:03:28 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Drawing2D;
|
|
|
|
|
using ryControls.Win32API;
|
|
|
|
|
|
|
|
|
|
namespace ryControls
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Chrome风格的多标签控件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class ChromeTabControl : TabControl
|
|
|
|
|
{
|
|
|
|
|
private Rectangle addRec;
|
|
|
|
|
private Color colorMouseOn = Color.Silver;
|
|
|
|
|
|
|
|
|
|
private Image close_Image;
|
|
|
|
|
private Image close_normalImage;
|
|
|
|
|
private Image TabIcon;
|
|
|
|
|
|
|
|
|
|
private Rectangle rectClose;
|
|
|
|
|
private Rectangle rectIcon;
|
|
|
|
|
private Rectangle rectFont;
|
|
|
|
|
private Color onSelectedColor1 = Color.White;
|
|
|
|
|
private Color onSelectedColor2 = Color.White;
|
|
|
|
|
private Color offSelectedColor1 = Color.FromArgb(192, 255, 255);
|
|
|
|
|
private Color offSelectedColor2 = Color.FromArgb(200, 66, 204, 255);
|
|
|
|
|
private Color MoveSelectedColor1 = Color.FromArgb(200, 66, 204, 255);
|
|
|
|
|
private Color MoveSelectedColor2 = Color.FromArgb(192, 255, 255);
|
|
|
|
|
private Color BottomLineColor = Color.FromArgb(188, 188, 188);
|
|
|
|
|
private SolidBrush brushFont = new SolidBrush(Color.Black);
|
|
|
|
|
private Color backcolor = System.Drawing.SystemColors.Control;
|
|
|
|
|
private Image _backgroundImage = null;
|
|
|
|
|
private Rectangle rctTabHeaderColor;
|
|
|
|
|
private Rectangle rctTabHeaderImage;
|
|
|
|
|
private int tabIndex = 0;
|
|
|
|
|
private int OverIndex = -1;
|
|
|
|
|
private int tabid = 0;
|
|
|
|
|
private bool AllSelected = false;
|
|
|
|
|
private Point tabPoint;
|
|
|
|
|
private TabPage _SourceTabPage = null;
|
|
|
|
|
private int _tabHOffset = 0;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置选项卡处于选中状态时第一背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置选项卡处于选中状态时第一背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "White")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color TabOnColorStart
|
|
|
|
|
{
|
|
|
|
|
get { return onSelectedColor1; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(onSelectedColor1))
|
|
|
|
|
{
|
|
|
|
|
onSelectedColor1 = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置选项卡处于选中状态时第二背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置选项卡处于选中状态时第二背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "White")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color TabOnColorEnd
|
|
|
|
|
{
|
|
|
|
|
get { return onSelectedColor2; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(onSelectedColor2))
|
|
|
|
|
{
|
|
|
|
|
onSelectedColor2 = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置选项卡处于非选中状态时第一背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置选项卡处于非选中状态时第一背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "192, 255, 255")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color TabOffColorStart
|
|
|
|
|
{
|
|
|
|
|
get { return offSelectedColor1; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(offSelectedColor1))
|
|
|
|
|
{
|
|
|
|
|
offSelectedColor1 = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置选项卡处于非选中状态时第二背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置选项卡处于非选中状态时第二背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "200, 66, 204, 255")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color TabOffColorEnd
|
|
|
|
|
{
|
|
|
|
|
get { return offSelectedColor2; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(offSelectedColor2))
|
|
|
|
|
{
|
|
|
|
|
offSelectedColor2 = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置鼠标移动到非选中状态选项卡时第一背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置鼠标移动到非选中状态选项卡时第一背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "200, 66, 204, 255")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color TabMoveColorStart
|
|
|
|
|
{
|
|
|
|
|
get { return MoveSelectedColor1; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(MoveSelectedColor1))
|
|
|
|
|
{
|
|
|
|
|
MoveSelectedColor1 = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置鼠标移动到非选中状态选项卡时第二背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置鼠标移动到非选中状态选项卡时第二背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "192, 255, 255")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color TabMoveColorEnd
|
|
|
|
|
{
|
|
|
|
|
get { return MoveSelectedColor2; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(MoveSelectedColor2))
|
|
|
|
|
{
|
|
|
|
|
MoveSelectedColor2 = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置选项卡工作区背景色.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置选项卡工作区背景色。")]
|
|
|
|
|
[DefaultValue(typeof(Color), "Control")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Color BackTabPageColor
|
|
|
|
|
{
|
|
|
|
|
get { return backcolor; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(backcolor))
|
|
|
|
|
{
|
|
|
|
|
backcolor = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置选项卡工作区背景图.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("设置选项卡工作区背景图。")]
|
|
|
|
|
[Browsable(true)]
|
|
|
|
|
public Image BackTabPageImage
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _backgroundImage;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value != null)
|
|
|
|
|
{
|
|
|
|
|
if (!value.Equals(_backgroundImage))
|
|
|
|
|
{
|
|
|
|
|
_backgroundImage = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_backgroundImage = null;
|
|
|
|
|
Invalidate();
|
|
|
|
|
Update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private bool _ShowCloseButton = true;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否显示关闭按钮
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("是否显示关闭按钮")]
|
|
|
|
|
public bool ShowCloseButton
|
|
|
|
|
{
|
|
|
|
|
get { return _ShowCloseButton; }
|
|
|
|
|
set { _ShowCloseButton = value; Invalidate(); Update(); }
|
|
|
|
|
}
|
|
|
|
|
private bool _ShowAddButton = true;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否显示新增按钮
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("是否显示新增按钮")]
|
|
|
|
|
public bool ShowAddButton
|
|
|
|
|
{
|
|
|
|
|
get { return _ShowAddButton; }
|
|
|
|
|
set { _ShowAddButton = value; Invalidate(); Update(); }
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否允许拖拽标签
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("是否允许拖拽标签")]
|
|
|
|
|
public bool AllowDragTab{get;set; } = false;
|
|
|
|
|
private int _TabMaxWidth = 200;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 标签最大宽度
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("标签最大宽度")]
|
|
|
|
|
public int TabMaxWidth
|
|
|
|
|
{
|
|
|
|
|
get { return _TabMaxWidth; }
|
|
|
|
|
set { _TabMaxWidth = value; Invalidate(); Update(); }
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 标签右键菜单
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("标签右键菜单")]
|
|
|
|
|
public ContextMenuStrip TabContextMenuStrip { get; set; } = null;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 鼠标按下标签时激发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("鼠标按下标签时激发")]
|
|
|
|
|
public event MouseEventHandler OnTabMouseDown;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 鼠标放开标签时激发
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("鼠标放开标签时激发")]
|
|
|
|
|
public event MouseEventHandler OnTabMouseUp;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Chrome风格的多标签控件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ChromeTabControl()
|
|
|
|
|
{
|
|
|
|
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint |
|
|
|
|
|
ControlStyles.SupportsTransparentBackColor | ControlStyles.ResizeRedraw |
|
|
|
|
|
ControlStyles.UserMouse, true);
|
|
|
|
|
|
|
|
|
|
this.ItemSize = new Size(TabMaxWidth, 25);
|
|
|
|
|
this.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
|
|
|
|
|
//this.AllowDrop = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//从资源文件(嵌入到程序集)里读取图片
|
|
|
|
|
close_Image = new Bitmap(this.GetType(), "close.png");
|
|
|
|
|
close_normalImage = new Bitmap(this.GetType(), "close_normal.png");
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
~ChromeTabControl()
|
|
|
|
|
{
|
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
protected virtual void Draw(Graphics g)
|
|
|
|
|
{
|
|
|
|
|
DrawBorder(g);
|
|
|
|
|
|
|
|
|
|
Rectangle rct = this.ClientRectangle;
|
|
|
|
|
rct.Inflate(-1, -1);
|
|
|
|
|
Rectangle rctTabArea = this.DisplayRectangle;
|
|
|
|
|
|
|
|
|
|
if (this.TabCount > 0)
|
|
|
|
|
{
|
|
|
|
|
rctTabHeaderColor = new Rectangle(rct.Left, rct.Top, rct.Width, rctTabArea.Top);
|
|
|
|
|
rctTabHeaderImage = new Rectangle(rct.Left - 1, rct.Top - 1, rct.Width + 3, rctTabArea.Top);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rctTabHeaderColor = new Rectangle(rct.Left, rct.Top, rct.Width, rctTabArea.Top + 24);
|
|
|
|
|
rctTabHeaderImage = new Rectangle(rct.Left - 1, rct.Top - 1, rct.Width + 3, rctTabArea.Top + 25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using (Bitmap overlay = new Bitmap(rctTabHeaderImage.Width, rctTabHeaderImage.Height))
|
|
|
|
|
{
|
|
|
|
|
using (Graphics gr = Graphics.FromImage(overlay))
|
|
|
|
|
{
|
|
|
|
|
gr.SmoothingMode = SmoothingMode.HighQuality;
|
|
|
|
|
|
|
|
|
|
if (_backgroundImage != null)
|
|
|
|
|
{
|
|
|
|
|
using (Brush brush = new TextureBrush(_backgroundImage, WrapMode.TileFlipXY))
|
|
|
|
|
gr.FillRectangle(brush, 0, 0, overlay.Width, overlay.Height);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g.FillRectangle(new SolidBrush(backcolor), 0, 0, rctTabHeaderColor.Width + 2, rctTabHeaderColor.Height);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g.DrawImage(overlay, rctTabHeaderImage, 1, 1, overlay.Width, overlay.Height, GraphicsUnit.Pixel);
|
|
|
|
|
g.DrawLine(new Pen(new SolidBrush(BottomLineColor), 1), 0, 28, this.ClientSize.Width, 28);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
protected virtual void DrawBorder(Graphics g)
|
|
|
|
|
{
|
|
|
|
|
Rectangle rct = this.ClientRectangle;
|
|
|
|
|
Rectangle rctTabArea = this.DisplayRectangle;
|
|
|
|
|
|
|
|
|
|
using (Pen pen = new Pen(Color.Silver))
|
|
|
|
|
{
|
|
|
|
|
pen.DashStyle = DashStyle.Solid;
|
|
|
|
|
|
|
|
|
|
g.DrawLine(pen, rct.X, rctTabArea.Y, rct.X, rct.Bottom - 1);
|
|
|
|
|
g.DrawLine(pen, rct.X, rct.Bottom - 1, rct.Width - 1, rct.Bottom - 1);
|
|
|
|
|
g.DrawLine(pen, rct.Width - 1, rct.Bottom - 1, rct.Width - 1, rctTabArea.Y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
/// <param name="rect"></param>
|
|
|
|
|
/// <param name="title"></param>
|
|
|
|
|
/// <param name="selected"></param>
|
|
|
|
|
/// <param name="mouseOver"></param>
|
|
|
|
|
protected virtual void DrawAll(Graphics g, Rectangle rect, string title, bool selected, bool mouseOver)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2021-09-03 09:31:31 +00:00
|
|
|
|
rectFont = new Rectangle(rect.X + TabStrLeftMargin, rect.Y + 9, rect.Width - 30, rect.Height - TabStrLeftMargin);
|
2020-11-28 07:03:28 +00:00
|
|
|
|
rectClose = new Rectangle(rect.X + rect.Width - 25, 11, 12, 12);
|
|
|
|
|
if(!ShowCloseButton)
|
|
|
|
|
{
|
|
|
|
|
rectFont.Width += 10;
|
|
|
|
|
}
|
|
|
|
|
bool haveIcon = false;
|
|
|
|
|
for (int i = 0; i < this.TabCount; i++)
|
|
|
|
|
{
|
|
|
|
|
var rect2 = this.GetTabRect(i);
|
|
|
|
|
if (this.ImageList != null && !this.TabPages[i].ImageIndex.Equals(-1))
|
|
|
|
|
{
|
|
|
|
|
if (this.TabPages[i].ImageIndex <= this.ImageList.Images.Count - 1)
|
|
|
|
|
{
|
|
|
|
|
TabIcon = this.ImageList.Images[this.TabPages[i].ImageIndex];
|
|
|
|
|
rectIcon = new Rectangle(rect2.X + 16, 8, 16, 16);
|
|
|
|
|
DrawTabIcon(g, rectIcon);
|
|
|
|
|
TabIcon.Dispose();
|
|
|
|
|
haveIcon = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(haveIcon)
|
|
|
|
|
{
|
|
|
|
|
rectFont.X += 7;
|
|
|
|
|
if (ShowCloseButton)
|
|
|
|
|
{
|
|
|
|
|
rectFont.Width -= 10;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
DrawRect(g, rect, selected, mouseOver);
|
|
|
|
|
DrawString(g, rectFont, title, Font);
|
|
|
|
|
DrawClose(g, rectClose, CloseHitTest(this.PointToClient(Cursor.Position)));
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
}
|
2021-09-03 09:31:31 +00:00
|
|
|
|
private int _radius = 15; //圆角半径
|
|
|
|
|
/// <summary>
|
|
|
|
|
///设置圆角半径
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("圆角半径")]
|
|
|
|
|
[DefaultValue(15)]//设置圆角半径,默认值为8,最小值为4px
|
|
|
|
|
public int Radius
|
|
|
|
|
{
|
|
|
|
|
get { return _radius; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_radius != value)
|
|
|
|
|
{
|
|
|
|
|
_radius = value < 4 ? 4 : value;
|
|
|
|
|
base.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private int _FontLeft = 10; //Tab文字左边距离
|
|
|
|
|
/// <summary>
|
|
|
|
|
///Tab文字左边距离
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("Tab文字左边距离")]
|
|
|
|
|
[DefaultValue(10)]//
|
|
|
|
|
public int TabStrLeftMargin
|
|
|
|
|
{
|
|
|
|
|
get { return _FontLeft; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_FontLeft != value)
|
|
|
|
|
{
|
|
|
|
|
_FontLeft = value < 4 ? 4 : value;
|
|
|
|
|
base.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-28 07:03:28 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
/// <param name="rect"></param>
|
|
|
|
|
/// <param name="selected"></param>
|
|
|
|
|
/// <param name="mouseOver"></param>
|
|
|
|
|
protected virtual void DrawRect(Graphics g, Rectangle rect, bool selected, bool mouseOver)
|
|
|
|
|
{
|
|
|
|
|
using (GraphicsPath path = new GraphicsPath())
|
|
|
|
|
{
|
|
|
|
|
path.AddBezier(
|
|
|
|
|
new Point(rect.X, rect.Bottom + 2),
|
|
|
|
|
new Point(rect.X + 3, rect.Bottom - 2),
|
|
|
|
|
new Point(rect.X + 3, rect.Bottom - 2),
|
|
|
|
|
new Point(rect.X, rect.Bottom + 2));
|
|
|
|
|
//path.AddLine(rect.X + 4, rect.Bottom - 4, rect.Left + 15 - 4, rect.Y + 4);
|
|
|
|
|
path.AddBezier(
|
2021-09-03 09:31:31 +00:00
|
|
|
|
new Point(rect.Left + _radius - 4, rect.Y + 4),
|
|
|
|
|
new Point(rect.Left + _radius - 3, rect.Y + 2),
|
|
|
|
|
new Point(rect.Left + _radius - 3, rect.Y + 2),
|
|
|
|
|
new Point(rect.Left + _radius, rect.Y));
|
2020-11-28 07:03:28 +00:00
|
|
|
|
//path.AddLine(rect.Left + 15, rect.Y, rect.Right - 15, rect.Y);
|
|
|
|
|
path.AddBezier(
|
2021-09-03 09:31:31 +00:00
|
|
|
|
new Point(rect.Right - _radius, rect.Y),
|
|
|
|
|
new Point(rect.Right - _radius + 3, rect.Y + 2),
|
|
|
|
|
new Point(rect.Right - _radius + 3, rect.Y + 2),
|
|
|
|
|
new Point(rect.Right - _radius + 4, rect.Y + 4));
|
2020-11-28 07:03:28 +00:00
|
|
|
|
//path.AddLine(rect.Right - 15 + 4, rect.Y + 4, rect.Right - 4, rect.Bottom - 4);
|
|
|
|
|
path.AddBezier(
|
|
|
|
|
new Point(rect.Right, rect.Bottom),
|
|
|
|
|
new Point(rect.Right - 3, rect.Bottom - 3),
|
|
|
|
|
new Point(rect.Right - 3, rect.Bottom - 3),
|
|
|
|
|
new Point(rect.Right + 1, rect.Bottom + 1));
|
|
|
|
|
|
|
|
|
|
Region region = new System.Drawing.Region(path);
|
|
|
|
|
|
2021-09-03 09:31:31 +00:00
|
|
|
|
g.DrawPath(new Pen(Color.Gray), path);
|
2020-11-28 07:03:28 +00:00
|
|
|
|
|
|
|
|
|
if (mouseOver)
|
|
|
|
|
{
|
|
|
|
|
using (LinearGradientBrush brush = new LinearGradientBrush(rect, MoveSelectedColor1, MoveSelectedColor2, LinearGradientMode.Vertical))
|
|
|
|
|
{
|
|
|
|
|
g.FillPath(brush, path);
|
|
|
|
|
}
|
|
|
|
|
//g.FillPath(new SolidBrush(MoveSelectedColor), path);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
using (LinearGradientBrush brush = selected ? new LinearGradientBrush(rect, onSelectedColor1, onSelectedColor2, LinearGradientMode.Vertical) : new LinearGradientBrush(rect, offSelectedColor1, offSelectedColor2, LinearGradientMode.Vertical))
|
|
|
|
|
{
|
|
|
|
|
g.FillPath(brush, path);
|
|
|
|
|
}
|
|
|
|
|
//g.FillPath(new SolidBrush(selected ? onSelectedColor : offSelectedColor), path);
|
|
|
|
|
}
|
|
|
|
|
g.DrawLine(new Pen(selected ? onSelectedColor2 : BottomLineColor, 1), rect.X + 1, rect.Bottom + 1, rect.Right, rect.Bottom + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 画标签文字
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
/// <param name="rect"></param>
|
|
|
|
|
/// <param name="title"></param>
|
|
|
|
|
/// <param name="font"></param>
|
|
|
|
|
protected virtual void DrawString(Graphics g, Rectangle rect, string title, Font font)
|
|
|
|
|
{
|
|
|
|
|
StringFormat format = new StringFormat();
|
|
|
|
|
format.Alignment = StringAlignment.Center;
|
|
|
|
|
g.DrawString(title, font, brushFont, rect, format);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 画标签图标
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
/// <param name="rect"></param>
|
|
|
|
|
protected virtual void DrawTabIcon(Graphics g, Rectangle rect)
|
|
|
|
|
{
|
|
|
|
|
g.DrawImageUnscaled(TabIcon, rect);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 画关闭按钮
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
/// <param name="rect"></param>
|
|
|
|
|
/// <param name="mouseOn"></param>
|
|
|
|
|
protected virtual void DrawClose(Graphics g, Rectangle rect, bool mouseOn)
|
|
|
|
|
{
|
|
|
|
|
if (ShowCloseButton)
|
|
|
|
|
{
|
|
|
|
|
if (mouseOn)
|
|
|
|
|
g.DrawImage(close_Image, rect);
|
|
|
|
|
else
|
|
|
|
|
g.DrawImage(close_normalImage, rect);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool CloseHitTest(Point cltPosition)
|
|
|
|
|
{
|
|
|
|
|
return rectClose.Contains(cltPosition);
|
|
|
|
|
}
|
2021-09-03 09:31:31 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取所有选项卡合起来的宽度
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private int GetTabTotalWidth()
|
|
|
|
|
{
|
|
|
|
|
return this.ItemSize.Width * this.TabCount;
|
|
|
|
|
}
|
2020-11-28 07:03:28 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnPaint(e);
|
|
|
|
|
Draw(e.Graphics);
|
|
|
|
|
Graphics g = e.Graphics;
|
|
|
|
|
|
2021-09-03 09:31:31 +00:00
|
|
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
|
|
|
g.CompositingQuality = CompositingQuality.HighQuality;
|
2020-11-28 07:03:28 +00:00
|
|
|
|
if (this.TabCount > 0)
|
|
|
|
|
{
|
2021-09-03 09:31:31 +00:00
|
|
|
|
if (GetTabTotalWidth() + 30 > this.ClientSize.Width || (this.ClientSize.Width - 30) / (this.TabCount) > this.ItemSize.Width)
|
2020-11-28 07:03:28 +00:00
|
|
|
|
{
|
2021-09-03 09:31:31 +00:00
|
|
|
|
if (this.ClientSize.Width < GetTabTotalWidth() + 30 || this.ItemSize.Width < TabMaxWidth)
|
2020-11-28 07:03:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (this.TabCount > 0)
|
|
|
|
|
{
|
|
|
|
|
this.ItemSize = new Size((this.ClientSize.Width - 30) / (this.TabCount), 25);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.ItemSize.Width > TabMaxWidth)
|
|
|
|
|
{
|
|
|
|
|
this.ItemSize = new Size(TabMaxWidth, 25);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-03 09:31:31 +00:00
|
|
|
|
addRec = new Rectangle(GetTabTotalWidth() + 5, 8, 16, 16); //指定显示区域的位置的大小
|
2020-11-28 07:03:28 +00:00
|
|
|
|
if (ShowAddButton)
|
|
|
|
|
{
|
|
|
|
|
e.Graphics.FillEllipse(new SolidBrush(colorMouseOn), addRec);
|
|
|
|
|
|
2021-09-03 09:31:31 +00:00
|
|
|
|
e.Graphics.DrawLine(new Pen(Color.White, 1.55f), GetTabTotalWidth() + 8, 16, GetTabTotalWidth() + 18, 16);
|
|
|
|
|
e.Graphics.DrawLine(new Pen(Color.White, 1.55f), GetTabTotalWidth() + 13, 11, GetTabTotalWidth() + 13, 21);
|
2020-11-28 07:03:28 +00:00
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < this.TabCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (tabIndex != 0)
|
|
|
|
|
{
|
|
|
|
|
if (tabIndex < this.TabCount)
|
|
|
|
|
{
|
|
|
|
|
if (tabIndex == i)
|
|
|
|
|
{
|
|
|
|
|
this.SelectedIndex = i;
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, true, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (OverIndex == i)
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, false, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, false, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((tabIndex - 1) == i)
|
|
|
|
|
{
|
|
|
|
|
this.SelectedIndex = i;
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, true, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (OverIndex == i)
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, false, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, false, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (this.SelectedIndex == i)
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, true, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (OverIndex == i)
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, false, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DrawAll(g, this.GetTabRect(i), this.TabPages[i].Text, false, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tabIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tabIndex = 0;
|
|
|
|
|
addRec = new Rectangle(10, 8, 16, 16); //指定显示区域的位置的大小
|
|
|
|
|
if (ShowAddButton)
|
|
|
|
|
{
|
|
|
|
|
e.Graphics.FillEllipse(new SolidBrush(colorMouseOn), addRec);
|
|
|
|
|
|
|
|
|
|
e.Graphics.DrawLine(new Pen(Color.White, 1.55f), 10 + 3, 16, 10 + 13, 16);
|
|
|
|
|
e.Graphics.DrawLine(new Pen(Color.White, 1.55f), 10 + 8, 11, 10 + 8, 21);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="m"></param>
|
|
|
|
|
protected override void WndProc(ref Message m)
|
|
|
|
|
{
|
|
|
|
|
base.WndProc(ref m);
|
|
|
|
|
|
|
|
|
|
if (m.Msg == (int)ryControls.Win32API.User32.Msgs.WM_NCHITTEST)
|
|
|
|
|
{
|
|
|
|
|
if (m.Result.ToInt32() == ryControls.Win32API.User32._HT_TRANSPARENT)
|
|
|
|
|
m.Result = (IntPtr)ryControls.Win32API.User32._HT_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m.Msg == (int)ryControls.Win32API.User32.Msgs.WM_LBUTTONDOWN)
|
|
|
|
|
{
|
|
|
|
|
if (this.TabCount > 1)
|
|
|
|
|
{
|
|
|
|
|
TabPage selectingTabPage = OverTab();
|
|
|
|
|
if (selectingTabPage != null)
|
|
|
|
|
{
|
|
|
|
|
int index = TabPages.IndexOf(selectingTabPage);
|
|
|
|
|
if (index != this.SelectedIndex)
|
|
|
|
|
{
|
|
|
|
|
if (!selectingTabPage.Enabled)
|
|
|
|
|
{
|
|
|
|
|
m.Result = new IntPtr(1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.SelectedTab = selectingTabPage;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseDown(e);
|
|
|
|
|
|
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
|
|
|
|
this._SourceTabPage = OverTab();
|
|
|
|
|
|
|
|
|
|
tabPoint = new Point(e.X, e.Y);
|
|
|
|
|
|
|
|
|
|
if (addRec.Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
colorMouseOn = Color.Orange;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (this.TabCount > 0)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < this.TabCount; i++)
|
|
|
|
|
{
|
|
|
|
|
Rectangle tabRect = new Rectangle(this.GetTabRect(i).X + this.GetTabRect(i).Width - 25, 11, 12, 12);
|
|
|
|
|
if (tabRect.Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
OnTabMouseDown?.Invoke(this, e);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseUp(e);
|
|
|
|
|
|
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
|
|
|
|
bool AscendingMove = false;
|
|
|
|
|
|
|
|
|
|
if (ShowAddButton && addRec.Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
colorMouseOn = Color.FromArgb(229, 233, 227);
|
|
|
|
|
AddTabPage("tabPage" + (this.TabCount + 1).ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.TabCount > 0)
|
|
|
|
|
{
|
|
|
|
|
if (!AllSelected)
|
|
|
|
|
{
|
|
|
|
|
Rectangle tabRect = new Rectangle(this.GetTabRect(this.SelectedIndex).X + this.GetTabRect(this.SelectedIndex).Width - 25, 11, 12, 12);
|
|
|
|
|
|
|
|
|
|
if (tabRect.Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
AscendingMove = true;
|
|
|
|
|
OnTabMouseUp?.Invoke(this, e);
|
|
|
|
|
if (ShowCloseButton)
|
|
|
|
|
{
|
|
|
|
|
tabIndex = this.SelectedIndex;
|
|
|
|
|
this.TabPages.Remove(this.SelectedTab);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AscendingMove = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Rectangle tabRect = new Rectangle(this.GetTabRect(tabid).X + this.GetTabRect(tabid).Width - 25, 11, 12, 12);
|
|
|
|
|
|
|
|
|
|
if (tabRect.Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
OnTabMouseUp?.Invoke(this, e);
|
|
|
|
|
AscendingMove = true;
|
|
|
|
|
if (ShowCloseButton)
|
|
|
|
|
{
|
|
|
|
|
this.TabPages.RemoveAt(tabid);
|
|
|
|
|
}
|
|
|
|
|
AllSelected = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AscendingMove = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._SourceTabPage != null && AllowDragTab)
|
|
|
|
|
{
|
|
|
|
|
TabPage currTabPage = GetTabPageFromXY(e.X, e.Y);
|
|
|
|
|
|
|
|
|
|
if ((currTabPage != null) && (!currTabPage.Equals(this._SourceTabPage)))
|
|
|
|
|
{
|
|
|
|
|
Rectangle currRect = base.GetTabRect(base.TabPages.IndexOf(currTabPage));
|
|
|
|
|
if ((base.TabPages.IndexOf(currTabPage) < base.TabPages.IndexOf(this._SourceTabPage)))
|
|
|
|
|
{
|
|
|
|
|
base.TabPages.Remove(this._SourceTabPage);
|
|
|
|
|
base.TabPages.Insert(base.TabPages.IndexOf(currTabPage), this._SourceTabPage);
|
|
|
|
|
base.SelectedTab = this._SourceTabPage;
|
|
|
|
|
}
|
|
|
|
|
else if ((base.TabPages.IndexOf(currTabPage) > base.TabPages.IndexOf(this._SourceTabPage)))
|
|
|
|
|
{
|
|
|
|
|
if (!AscendingMove)
|
|
|
|
|
{
|
|
|
|
|
base.TabPages.Remove(this._SourceTabPage);
|
|
|
|
|
base.TabPages.Insert(base.TabPages.IndexOf(currTabPage) + 1, this._SourceTabPage);
|
|
|
|
|
base.SelectedTab = this._SourceTabPage;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Button == MouseButtons.Right)
|
|
|
|
|
{
|
|
|
|
|
if(TabContextMenuStrip!=null)
|
|
|
|
|
{
|
|
|
|
|
TabContextMenuStrip.Show(MousePosition);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this._SourceTabPage = null;
|
|
|
|
|
base.Cursor = Cursors.Default;
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnMouseLeave(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseLeave(e);
|
|
|
|
|
OverIndex = -1;
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseMove(e);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.TabCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (this.SelectedIndex != i && this.GetTabRect(i).Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
OverIndex = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
OverIndex = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addRec.Contains(e.Location))
|
|
|
|
|
{
|
|
|
|
|
colorMouseOn = Color.OrangeRed;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
colorMouseOn = Color.Silver;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((e.Button == MouseButtons.Left) && (this._SourceTabPage != null) && AllowDragTab)
|
|
|
|
|
{
|
|
|
|
|
TabPage currTabPage = GetTabPageFromXY(e.X, e.Y);
|
|
|
|
|
if ((currTabPage != null))
|
|
|
|
|
{
|
|
|
|
|
Rectangle currRect = base.GetTabRect(base.TabPages.IndexOf(currTabPage));
|
|
|
|
|
if ((base.TabPages.IndexOf(currTabPage) < base.TabPages.IndexOf(this._SourceTabPage)))
|
|
|
|
|
{
|
|
|
|
|
base.Cursor = Cursors.PanWest;
|
|
|
|
|
}
|
|
|
|
|
else if ((base.TabPages.IndexOf(currTabPage) > base.TabPages.IndexOf(this._SourceTabPage)))
|
|
|
|
|
{
|
|
|
|
|
base.Cursor = Cursors.PanEast;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
base.Cursor = Cursors.Default;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.Cursor = Cursors.No;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.Cursor = Cursors.Default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private TabPage GetTabPageFromXY(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i <= base.TabPages.Count - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
if (base.GetTabRect(i).Contains(x, y))
|
|
|
|
|
{
|
|
|
|
|
return base.TabPages[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnSelecting(TabControlCancelEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnSelecting(e);
|
|
|
|
|
|
|
|
|
|
if (OverIndex > -1)
|
|
|
|
|
{
|
|
|
|
|
Rectangle tabRect = new Rectangle(this.GetTabRect(e.TabPageIndex).X + this.GetTabRect(e.TabPageIndex).Width - 25, 11, 12, 12);
|
|
|
|
|
|
|
|
|
|
if (tabRect.Contains(tabPoint))
|
|
|
|
|
{
|
|
|
|
|
e.Cancel = true;
|
|
|
|
|
AllSelected = true;
|
|
|
|
|
tabid = e.TabPageIndex;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AllSelected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AllSelected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
protected override void OnResize(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnResize(e);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override Rectangle DisplayRectangle
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
Rectangle rect = base.DisplayRectangle;
|
|
|
|
|
return new Rectangle(rect.Left - 3, rect.Top, rect.Width + 6, rect.Height + 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加新标签
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tabName"></param>
|
|
|
|
|
public void AddTabPage(string tabName)
|
|
|
|
|
{
|
|
|
|
|
TabPages.Add(tabName);
|
|
|
|
|
SelectTab(TabPages.Count - 1);
|
|
|
|
|
this.SelectedTab.AutoScroll = true;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected virtual TabPage OverTab()
|
|
|
|
|
{
|
|
|
|
|
TabPage over = null;
|
|
|
|
|
|
|
|
|
|
Point pt = this.PointToClient(Cursor.Position);
|
|
|
|
|
ryControls.Win32API.User32.TCHITTESTINFO mouseInfo = new ryControls.Win32API.User32.TCHITTESTINFO(pt, ryControls.Win32API.User32.TabControlHitTest.TCHT_ONITEM);
|
|
|
|
|
int currentTabIndex = ryControls.Win32API.User32.SendMessage(this.Handle, ryControls.Win32API.User32._TCM_HITTEST, IntPtr.Zero, ref mouseInfo);
|
|
|
|
|
|
|
|
|
|
if (currentTabIndex > -1)
|
|
|
|
|
{
|
|
|
|
|
Rectangle currentTabRct = this.GetTabRect(currentTabIndex);
|
|
|
|
|
|
|
|
|
|
if (currentTabIndex == 0)
|
|
|
|
|
currentTabRct.X += _tabHOffset;
|
|
|
|
|
|
|
|
|
|
if (currentTabRct.Contains(pt))
|
|
|
|
|
over = this.TabPages[currentTabIndex] as TabPage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return over;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|