using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DPumpHydr.WinFrmUI.WenSkin.Properties;
using WinTabControl.Win32;
namespace DPumpHydr.WinFrmUI.WenSkin.Controls
{
[ToolboxBitmap(typeof(TabControl))]
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.Pink;
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;
[Description("添加选项卡按钮是否生效")]
public bool AddButton { get; set; }
///
/// 设置选项卡处于选中状态时第一背景色.
///
[Description("设置选项卡处于选中状态时第一背景色。")]
[DefaultValue(typeof(Color), "White")]
[Browsable(true)]
public Color TabOnColorState
{
get { return onSelectedColor1; }
set
{
if (!value.Equals(onSelectedColor1))
{
onSelectedColor1 = value;
Invalidate();
Update();
}
}
}
///
/// 设置选项卡处于选中状态时第二背景色.
///
[Description("设置选项卡处于选中状态时第二背景色。")]
[DefaultValue(typeof(Color), "Pink")]
[Browsable(true)]
public Color TabOnColorEnd
{
get { return onSelectedColor2; }
set
{
if (!value.Equals(onSelectedColor2))
{
onSelectedColor2 = value;
Invalidate();
Update();
}
}
}
///
/// 设置选项卡处于非选中状态时第一背景色.
///
[Description("设置选项卡处于非选中状态时第一背景色。")]
[DefaultValue(typeof(Color), "192, 255, 255")]
[Browsable(true)]
public Color TabOffColorState
{
get { return offSelectedColor1; }
set
{
if (!value.Equals(offSelectedColor1))
{
offSelectedColor1 = value;
Invalidate();
Update();
}
}
}
///
/// 设置选项卡处于非选中状态时第二背景色.
///
[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();
}
}
}
///
/// 设置鼠标移动到非选中状态选项卡时第一背景色.
///
[Description("设置鼠标移动到非选中状态选项卡时第一背景色。")]
[DefaultValue(typeof(Color), "200, 66, 204, 255")]
[Browsable(true)]
public Color TabMoveColorState
{
get { return MoveSelectedColor1; }
set
{
if (!value.Equals(MoveSelectedColor1))
{
MoveSelectedColor1 = value;
Invalidate();
Update();
}
}
}
///
/// 设置鼠标移动到非选中状态选项卡时第二背景色.
///
[Description("设置鼠标移动到非选中状态选项卡时第二背景色。")]
[DefaultValue(typeof(Color), "192, 255, 255")]
[Browsable(true)]
public Color TabMoveColorEnd
{
get { return MoveSelectedColor2; }
set
{
if (!value.Equals(MoveSelectedColor2))
{
MoveSelectedColor2 = value;
Invalidate();
Update();
}
}
}
///
/// 设置选项卡工作区背景色.
///
[Description("设置选项卡工作区背景色。")]
[DefaultValue(typeof(Color), "Control")]
[Browsable(true)]
public Color BackTabPageColor
{
get { return backcolor; }
set
{
if (!value.Equals(backcolor))
{
backcolor = value;
Invalidate();
Update();
}
}
}
///
/// 设置选项卡工作区背景图.
///
[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();
}
}
}
public ChromeTabControl()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint |
ControlStyles.SupportsTransparentBackColor | ControlStyles.ResizeRedraw |
ControlStyles.UserMouse, true);
this.ItemSize = new Size(200, 25);
this.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
//this.AllowDrop = true;
//从资源文件(嵌入到程序集)里读取图片
close_Image = Resources.close;
close_normalImage = Resources.close_normal;
}
~ChromeTabControl()
{
GC.SuppressFinalize(this);
}
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);
}
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);
}
protected virtual void DrawAll(Graphics g, Rectangle rect, string title, bool selected, bool mouseOver)
{
try
{
rectFont = new Rectangle(rect.X + 35, rect.Y + 9, rect.Width - 60, rect.Height - 10);
rectClose = new Rectangle(rect.X + rect.Width - 25, 11, 12, 12);
drawRect(g, rect, selected, mouseOver);
drawString(g, rectFont, title, Font);
drawClose(g, rectClose, CloseHitTest(this.PointToClient(Cursor.Position)));
for (int i = 0; i < this.TabCount; i++)
{
rect = 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(rect.X + 16, 8, 16, 16);
drawTabIcon(g, rectIcon);
TabIcon.Dispose();
}
}
}
}
catch { }
}
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 + 15 - 4, rect.Y + 4),
new Point(rect.Left + 15 - 3, rect.Y + 2),
new Point(rect.Left + 15 - 3, rect.Y + 2),
new Point(rect.Left + 15, rect.Y));
//path.AddLine(rect.Left + 15, rect.Y, rect.Right - 15, rect.Y);
path.AddBezier(
new Point(rect.Right - 15, rect.Y),
new Point(rect.Right - 15 + 3, rect.Y + 2),
new Point(rect.Right - 15 + 3, rect.Y + 2),
new Point(rect.Right - 15 + 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.Black), 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);
}
protected virtual void drawString(Graphics g, Rectangle rect, string title, Font font)
{
g.DrawString(title, font, brushFont, rect);
}
protected virtual void drawTabIcon(Graphics g, Rectangle rect)
{
g.DrawImageUnscaled(TabIcon, rect);
}
protected virtual void drawClose(Graphics g, Rectangle rect, bool mouseOn)
{
if (mouseOn)
g.DrawImage(close_Image, rect);
else
g.DrawImage(close_normalImage, rect);
}
private bool CloseHitTest(Point cltPosition)
{
return rectClose.Contains(cltPosition);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Draw(e.Graphics);
Graphics g = e.Graphics;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
if (this.TabCount > 0)
{
if ((this.ItemSize.Width * this.TabCount) + 30 > this.ClientSize.Width || (this.ClientSize.Width - 30) / (this.TabCount) > this.ItemSize.Width)
{
if (this.ClientSize.Width < (this.TabCount * this.ItemSize.Width) + 30 || this.ItemSize.Width < 200)
{
if (this.TabCount > 0)
{
this.ItemSize = new Size((this.ClientSize.Width - 30) / (this.TabCount), 25);
}
}
if (this.ItemSize.Width > 200)
{
this.ItemSize = new Size(200, 25);
}
}
addRec = new Rectangle((this.ItemSize.Width * this.TabCount) + 5, 8, 16, 16); //指定显示区域的位置的大小
e.Graphics.FillEllipse(new SolidBrush(colorMouseOn), addRec);
e.Graphics.DrawLine(new Pen(Color.White, 1.55f), (this.ItemSize.Width * this.TabCount) + 8, 16, (this.ItemSize.Width * this.TabCount) + 18, 16);
e.Graphics.DrawLine(new Pen(Color.White, 1.55f), (this.ItemSize.Width * this.TabCount) + 13, 11, (this.ItemSize.Width * this.TabCount) + 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); //指定显示区域的位置的大小
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);
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == (int)User32.Msgs.WM_NCHITTEST)
{
if (m.Result.ToInt32() == User32._HT_TRANSPARENT)
m.Result = (IntPtr)User32._HT_CLIENT;
}
if (m.Msg == (int)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;
}
}
}
}
}
}
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;
}
}
this.Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left)
{
bool AscendingMove = false;
if (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;
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))
{
AscendingMove = true;
this.TabPages.RemoveAt(tabid);
AllSelected = false;
}
else
{
AscendingMove = false;
}
}
if (this._SourceTabPage != null)
{
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;
}
}
}
}
}
}
this._SourceTabPage = null;
base.Cursor = Cursors.Default;
this.Invalidate();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
OverIndex = -1;
Invalidate();
}
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))
{
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;
}
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;
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
}
public override Rectangle DisplayRectangle
{
get
{
Rectangle rect = base.DisplayRectangle;
return new Rectangle(rect.Left - 3, rect.Top, rect.Width + 6, rect.Height + 3);
}
}
public void AddTabPage(string tabName)
{
if (!AddButton)
return;
TabPages.Add(tabName);
SelectTab(TabPages.Count - 1);
this.SelectedTab.AutoScroll = true;
}
protected virtual TabPage OverTab()
{
TabPage over = null;
Point pt = this.PointToClient(Cursor.Position);
User32.TCHITTESTINFO mouseInfo = new User32.TCHITTESTINFO(pt, User32.TabControlHitTest.TCHT_ONITEM);
int currentTabIndex = User32.SendMessage(this.Handle, 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;
}
}
}