------ #### ryControls V3.0.2109.0301 - *.[改进]RichTextBox2控件现在可以自由选择字符区间。 - *.[改进]RichTextBox2控件改用Courier New等宽字体。
998 lines
54 KiB
C#
998 lines
54 KiB
C#
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
|
||
{
|
||
rectFont = new Rectangle(rect.X + TabStrLeftMargin, rect.Y + 9, rect.Width - 30, rect.Height - TabStrLeftMargin);
|
||
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 { }
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
}
|
||
/// <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(
|
||
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));
|
||
//path.AddLine(rect.Left + 15, rect.Y, rect.Right - 15, rect.Y);
|
||
path.AddBezier(
|
||
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));
|
||
//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);
|
||
|
||
g.DrawPath(new Pen(Color.Gray), path);
|
||
|
||
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);
|
||
}
|
||
/// <summary>
|
||
/// 获取所有选项卡合起来的宽度
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private int GetTabTotalWidth()
|
||
{
|
||
return this.ItemSize.Width * this.TabCount;
|
||
}
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected override void OnPaint(PaintEventArgs e)
|
||
{
|
||
base.OnPaint(e);
|
||
Draw(e.Graphics);
|
||
Graphics g = e.Graphics;
|
||
|
||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||
if (this.TabCount > 0)
|
||
{
|
||
if (GetTabTotalWidth() + 30 > this.ClientSize.Width || (this.ClientSize.Width - 30) / (this.TabCount) > this.ItemSize.Width)
|
||
{
|
||
if (this.ClientSize.Width < GetTabTotalWidth() + 30 || this.ItemSize.Width < TabMaxWidth)
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
|
||
addRec = new Rectangle(GetTabTotalWidth() + 5, 8, 16, 16); //指定显示区域的位置的大小
|
||
if (ShowAddButton)
|
||
{
|
||
e.Graphics.FillEllipse(new SolidBrush(colorMouseOn), addRec);
|
||
|
||
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);
|
||
}
|
||
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;
|
||
}
|
||
}
|
||
}
|