C#仿QQ皮肤-TabControl控件实现

  • Post author:
  • Post category:其他

导读部分
————————————————————————————————————-
C#仿QQ皮肤-实现原理系列文章导航
http://www.sufeinet.com/forum.php?mod=viewthread&tid=2

 

     

其它这次的这个控件的改变并是太大,只是从选中与不选中,和图标上下了一些功夫。

大家先看一下效果吧


 

这个图片上没有图标,是可以直接设置的这个大家等下下载一下我的源代码,可以自己设置一下。

 

 
public
 
partial
 
class
 CTabControl : System.Windows.Forms.TabControl

 

通过上面一行代码我们可以看到这个控件是继承Windows的TabContrl而来的,这也就是说Windows自带的控件所具有的功能在这里都会自动继承而来。

我们先来看看   DrawControl(Graphics g)方法。

 

    
internal
 
void
 DrawControl(Graphics g)
        {
            

if
 (
!
Visible)
                

return
;
            

//
Rectangle TabControlArea = new Rectangle(2, 2, this.Width – 3, this.Height – 2); 


            Rectangle TabControlArea 
=
 
this
.ClientRectangle;

            Rectangle TabArea 
=
 
new
 Rectangle(
3

24

this
.ClientRectangle.Width 

 
7

this
.ClientRectangle.Height 

 
28
);
//
 this.DisplayRectangle;

            
//
—————————-
            

//
 控件内部颜色


            Brush br 
=
 
new
 SolidBrush(Color.Transparent);

            g.FillRectangle(br, TabControlArea);

            br.Dispose();
            
//
—————————-

            
//
—————————-
            

//
 draw border


            
int
 nDelta 
=
 SystemInformation.Border3DSize.Width;

            
//
默认的控件边框颜色


            Pen border 
=
 
new
 Pen(SkinHelp.Defalutborder);
            g.DrawRectangle(border, TabArea);
            border.Dispose();
            

//
—————————-

            
//
—————————-
            

//
 clip region for drawing tabs


            Region rsaved 
=
 g.Clip;
            Rectangle rreg;

            
int
 nWidth 
=
 TabArea.Width 
+
 nMargin;
            

if
 (bUpDown)
            {
                

//
 exclude updown control for painting


                
if
 (Win32.IsWindowVisible(scUpDown.Handle))
                {
                    Rectangle rupdown 

=
 
new
 Rectangle();
                    Win32.GetWindowRect(scUpDown.Handle, 

ref
 rupdown);
                    Rectangle rupdown2 

=
 
this
.RectangleToClient(rupdown);

                    nWidth 
=
 rupdown2.X;
                }
            }

            rreg 
=
 
new
 Rectangle(TabArea.Left, TabControlArea.Top, nWidth 

 nMargin, TabControlArea.Height);

            g.SetClip(rreg);

            
//
 draw tabs


            
for
 (
int
 i 
=
 
0
; i 
<
 
this
.TabCount; i
++
)
                DrawTab(g, 

this
.TabPages[i], i);

            g.Clip 
=
 rsaved;
            

//
—————————-

            
//
yuterz
            

//
—————————-
            

//
 draw background to cover flat border areas


            
if
 (
this
.SelectedTab 
!=
 
null
)
            {
                TabPage tabPage 

=
 
this
.SelectedTab;
                Color color 

=
 tabPage.BackColor;
                

//
border = new Pen(color);


                border 
=
 
new
 Pen(Color.Green);
                TabArea.Offset(

1

1
);
                TabArea.Width 

-=
 
2
;
                TabArea.Height 

-=
 
2
;

                
//
g.DrawRectangle(border, TabArea);


                TabArea.Width 
-=
 
1
;
                TabArea.Height 

-=
 
1
;
                

//
 g.DrawRectangle(border, TabArea);



                border.Dispose();

            }

            
//
—————————-


        }

在这里我设置了默认的背景色和边框的颜色

当然大家也要吧自己设置

只要修改相应代码就行了,看注释就明白了。

这些完成了我们再来看看绘制Tab的事件

 

   
internal
 
void
 DrawTab(Graphics g, TabPage tabPage, 
int
 nIndex)
        {

            Rectangle recBounds 
=
 
this
.GetTabRect(nIndex);
            RectangleF tabTextArea 

=
 (RectangleF)
this
.GetTabRect(nIndex);

            
bool
 bSelected 
=
 (
this
.SelectedIndex 
==
 nIndex);

            Point[] pt 
=
 
new
 Point[
7
];
            

if
 (
this
.Alignment 
==
 TabAlignment.Top)
            {
                pt[

0

=
 
new
 Point(recBounds.Left, recBounds.Bottom);
                pt[

1

=
 
new
 Point(recBounds.Left, recBounds.Top 
+
 
3
);
                pt[

2

=
 
new
 Point(recBounds.Left 
+
 
3
, recBounds.Top);
                pt[

3

=
 
new
 Point(recBounds.Right 

 
3
, recBounds.Top);
                pt[

4

=
 
new
 Point(recBounds.Right, recBounds.Top 
+
 
3
);
                pt[

5

=
 
new
 Point(recBounds.Right, recBounds.Bottom);
                pt[

6

=
 
new
 Point(recBounds.Left, recBounds.Bottom);
            }
            

else

            {
                pt[

0

=
 
new
 Point(recBounds.Left, recBounds.Top);
                pt[

1

=
 
new
 Point(recBounds.Right, recBounds.Top);
                pt[

2

=
 
new
 Point(recBounds.Right, recBounds.Bottom 

 
3
);
                pt[

3

=
 
new
 Point(recBounds.Right 

 
3
, recBounds.Bottom);
                pt[

4

=
 
new
 Point(recBounds.Left 
+
 
3
, recBounds.Bottom);
                pt[

5

=
 
new
 Point(recBounds.Left, recBounds.Bottom 

 
3
);
                pt[

6

=
 
new
 Point(recBounds.Left, recBounds.Top);
            }

            
//
—————————-
            

//
 fill this tab with background color
            

//
Brush br = new SolidBrush(tabPage.BackColor);


            Brush br 
=
 
new
 SolidBrush(Color.White);

            
//
—————————-

            
//
—————————-
            

//
 draw border
            

//
g.DrawRectangle(SystemPens.ControlDark, recBounds);
            

//
 g.DrawPolygon(SystemPens.ControlDark, pt);

            
//
默认的左右边框没有被选中时的标题边框颜色


            g.DrawPolygon(
new
 Pen(SkinHelp.ControlBorderBackColor), pt);

            
if
 (bSelected)
            {
                

//
—————————-
                

//
 clear bottom lines


                Pen pen 
=
 
new
 Pen(tabPage.BackColor);

                
switch
 (
this
.Alignment)
                {
                    

case
 TabAlignment.Top:
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Bottom, recBounds.Right 

 
1
, recBounds.Bottom);
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Bottom 
+
 
1
, recBounds.Right 

 
1
, recBounds.Bottom 
+
 
1
);
                        

break
;

                    
case
 TabAlignment.Bottom:
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Top, recBounds.Right 

 
1
, recBounds.Top);
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Top 

 
1
, recBounds.Right 

 
1
, recBounds.Top 

 
1
);
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Top 

 
2
, recBounds.Right 

 
1
, recBounds.Top 

 
2
);
                        

break
;
                }

                g.FillPolygon(br, pt);
                br.Dispose();

                
//
左右被选中时颜色


                g.DrawPolygon(
new
 Pen(Color.Red), pt);
                g.DrawLine(

new
 Pen(Color.White, 2f), recBounds.Left 
+
 
1
, recBounds.Bottom 
+
 
1
, recBounds.Right 

 
1
, recBounds.Bottom 
+
 
1
);

                pen.Dispose();
                
//
—————————-


            }
            

else

            {
                

//
没有选中时的下边框颜色


                g.DrawLine(
new
 Pen(SkinHelp.ControlBorderBackColor), recBounds.Left 
+
 
1
, recBounds.Bottom, recBounds.Right 

 
1
, recBounds.Bottom);
            }

            
if
 ((tabPage.ImageIndex 
>=
 
0

&&
 (ImageList 
!=
 
null

&&
 (ImageList.Images[tabPage.ImageIndex] 
!=
 
null
))
            {
                

int
 nLeftMargin 
=
 
8
;
                

int
 nRightMargin 
=
 
2
;

                Image img 
=
 ImageList.Images[tabPage.ImageIndex];

                Rectangle rimage 
=
 
new
 Rectangle(recBounds.X 
+
 nLeftMargin, recBounds.Y 
+
 
1
, img.Width, img.Height);

                
//
 adjust rectangles


                
float
 nAdj 
=
 (
float
)(nLeftMargin 
+
 img.Width 
+
 nRightMargin);

                rimage.Y 
+=
 (recBounds.Height 

 img.Height) 
/
 
2
;
                tabTextArea.X 

+=
 nAdj;
                tabTextArea.Width 

-=
 nAdj;

                
//
 draw icon


                g.DrawImage(img, rimage);
            }

            
//
 draw string


            StringFormat stringFormat 
=
 
new
 StringFormat();
            stringFormat.Alignment 

=
 StringAlignment.Center;
            stringFormat.LineAlignment 

=
 StringAlignment.Center;

            br 
=
 
new
 SolidBrush(SkinHelp.FontColor);

            g.DrawString(tabPage.Text, Font, br, tabTextArea, stringFormat);

            
if
 (nIndex 
==
 
0
)
            {
                

//
最左上角标题上的竖线


                Pen pen 
=
 
new
 Pen(SkinHelp.ControlBorderBackColor);
                g.DrawLine(pen, 

3

5

3
, recBounds.Height 
+
 
3
);
            }
        }

在这里主要是给左右没有选中,和选中时的标题加颜色。还有就是最左上角地那条线的颜色。大家可以根据我们代码进行修改,

找到适应自己软件或者是自己喜欢的颜色进行配置。我这里是用一个红色来代替,这样主要是为了色差大,容易区分。

接下来我们还要对上面的ICON进行处理处理访求 如下

 

  
internal
 
void
 DrawIcons(Graphics g)
        {
            

if
 ((leftRightImages 
==
 
null

||
 (leftRightImages.Images.Count 
!=
 
4
))
                

return
;

            
//
 calc positions


            Rectangle TabControlArea 
=
 
this
.ClientRectangle;

            Rectangle r0 
=
 
new
 Rectangle();
            Win32.GetClientRect(scUpDown.Handle, 

ref
 r0);

            
//
 当Tab多时背景颜色


            Brush br 
=
 
new
 SolidBrush(Color.Transparent);

            g.FillRectangle(br, r0);
            br.Dispose();

            
//
当Tab多时边框颜色


            Pen border 
=
 
new
 Pen(SkinHelp.ControlBorderBackColor);
            Rectangle rborder 

=
 
new
 Rectangle(
1

1

36

19
);
            rborder.Inflate(


1


1
);
            g.DrawRectangle(border, rborder);
            border.Dispose();

            
int
 nMiddle 
=
 (r0.Width 
/
 
2
);
            

int
 nTop 
=
 (r0.Height 

 
16

/
 
2
;
            

int
 nLeft 
=
 (nMiddle 

 
16

/
 
2
;

            Rectangle r1 
=
 
new
 Rectangle(nLeft, nTop, 
16

16
);
            Rectangle r2 

=
 
new
 Rectangle(nMiddle 
+
 nLeft, nTop, 
16

16
);

            
//
 draw buttons


            Image img 
=
 leftRightImages.Images[
1
];
            

if
 (img 
!=
 
null
)
            {
                

if
 (
this
.TabCount 
>
 
0
)
                {
                    Rectangle r3 

=
 
this
.GetTabRect(
0
);
                    

if
 (r3.Left 
<
 TabControlArea.Left)
                        g.DrawImage(img, r1);
                    

else

                    {
                        img 

=
 leftRightImages.Images[
3
];
                        

if
 (img 
!=
 
null
)
                            g.DrawImage(img, r1);
                    }
                }
            }

            img 
=
 leftRightImages.Images[
0
];
            

if
 (img 
!=
 
null
)
            {
                

if
 (
this
.TabCount 
>
 
0
)
                {
                    Rectangle r3 

=
 
this
.GetTabRect(
this
.TabCount 

 
1
);
                    

if
 (r3.Right 
>
 (TabControlArea.Width 

 r0.Width))
                        g.DrawImage(img, r2);
                    

else

                    {
                        img 

=
 leftRightImages.Images[
2
];
                        

if
 (img 
!=
 
null
)
                            g.DrawImage(img, r2);
                    }
                }
            }
    

方法很简单主要是处理一下不同图标放上去的效果。会根据图标的不同而适应不同的效果。

感觉这个控件的语言可表达性不强主要是看代码,我把这个类的相关代码放上来大家看看,多多交流,多提保定意见。

感谢大家的支持。

 

using
 System;

using
 System.Collections;

using
 System.ComponentModel;

using
 System.Drawing;

using
 System.Drawing.Drawing2D;

using
 System.Data;

using
 System.Windows.Forms;

using
 System.Drawing.Design;

using
 System.ComponentModel.Design;

using
 System.Runtime.InteropServices;

using
 System.Diagnostics;

using
 System.IO;

using
 bxyztSkin.Properties;


namespace
 bxyztSkin.CControls
{
    

public
 
partial
 
class
 CTabControl : System.Windows.Forms.TabControl
    {
        

private
 System.ComponentModel.Container components 
=
 
null
;
        

private
 SubClass scUpDown 
=
 
null
;
        

private
 
bool
 bUpDown;
        

private
 ImageList leftRightImages 
=
 
null
;
        

private
 
const
 
int
 nMargin 
=
 
5
;
        

private
 Color mBackColor 
=
 SystemColors.Control;

        
public
 CTabControl()
        {

            
//
 This call is required by the Windows.Forms Form Designer.


            InitializeComponent();

            
//
 double buffering


            
this
.SetStyle(ControlStyles.UserPaint, 
true
);
            

this
.SetStyle(ControlStyles.AllPaintingInWmPaint, 
true
);
            

this
.SetStyle(ControlStyles.DoubleBuffer, 
true
);
            

this
.SetStyle(ControlStyles.ResizeRedraw, 
true
);
            

this
.SetStyle(ControlStyles.SupportsTransparentBackColor, 
true
);
            

//
 this.BackColor = Color.Transparent;


            bUpDown 
=
 
false
;

            
this
.ControlAdded 
+=
 
new
 ControlEventHandler(FlatTabControl_ControlAdded);
            

this
.ControlRemoved 
+=
 
new
 ControlEventHandler(FlatTabControl_ControlRemoved);
            

this
.SelectedIndexChanged 
+=
 
new
 EventHandler(FlatTabControl_SelectedIndexChanged);

            leftRightImages 
=
 
new
 ImageList();
            

//
leftRightImages.ImageSize = new Size(16, 16); 
//
 default



            Bitmap updownImage 

=
 
new
 Bitmap(Resources.TabIcons);

            
if
 (updownImage 
!=
 
null
)
            {
                updownImage.MakeTransparent(Color.White);
                leftRightImages.Images.AddStrip(updownImage);
            }

        }

        
public
 
void
 ChangeSkinColor()
        {
            IntPtr hDC 

=
 Win32.GetWindowDC(
this
.Handle);
            Graphics gdc 

=
 Graphics.FromHdc(hDC);

            
for
 (
int
 i 
=
 
0
; i 
<
 
this
.TabCount; i
++
)
                DrawTab(gdc, 

this
.TabPages[i], i);

            Win32.ReleaseDC(
this
.Handle, hDC);
            gdc.Dispose();

        }

        
protected
 
override
 
void
 Dispose(
bool
 disposing)
        {
            

if
 (disposing)
            {
                

if
 (components 
!=
 
null
)
                {
                    components.Dispose();
                }

                leftRightImages.Dispose();
            }
            
base
.Dispose(disposing);
        }

        
protected
 
override
 
void
 OnPaint(PaintEventArgs e)
        {

            
base
.OnPaint(e);

            DrawControl(e.Graphics);

        }

        
protected
 
override
 
void
 OnResize(EventArgs e)
        {
            

base
.OnResize(e);

            GraphicsPath g 
=
 
new
 GraphicsPath();
            g.AddRectangle(

new
 Rectangle(
3

2

this
.Width 

 
6

this
.Height 

 
5
));
            

this
.Region 
=
 
new
 Region(g);
        }

       
internal
 
void
 DrawControl(Graphics g)
        {
            

if
 (
!
Visible)
                

return
;
            

//
Rectangle TabControlArea = new Rectangle(2, 2, this.Width – 3, this.Height – 2); 


            Rectangle TabControlArea 
=
 
this
.ClientRectangle;

            Rectangle TabArea 
=
 
new
 Rectangle(
3

24

this
.ClientRectangle.Width 

 
7

this
.ClientRectangle.Height 

 
28
);
//
 this.DisplayRectangle;

            
//
—————————-
            

//
 控件内部颜色


            Brush br 
=
 
new
 SolidBrush(Color.Transparent);

            g.FillRectangle(br, TabControlArea);

            br.Dispose();
            
//
—————————-

            
//
—————————-
            

//
 draw border


            
int
 nDelta 
=
 SystemInformation.Border3DSize.Width;

            
//
默认的控件边框颜色


            Pen border 
=
 
new
 Pen(SkinHelp.Defalutborder);
            g.DrawRectangle(border, TabArea);
            border.Dispose();
            

//
—————————-

            
//
—————————-
            

//
 clip region for drawing tabs


            Region rsaved 
=
 g.Clip;
            Rectangle rreg;

            
int
 nWidth 
=
 TabArea.Width 
+
 nMargin;
            

if
 (bUpDown)
            {
                

//
 exclude updown control for painting


                
if
 (Win32.IsWindowVisible(scUpDown.Handle))
                {
                    Rectangle rupdown 

=
 
new
 Rectangle();
                    Win32.GetWindowRect(scUpDown.Handle, 

ref
 rupdown);
                    Rectangle rupdown2 

=
 
this
.RectangleToClient(rupdown);

                    nWidth 
=
 rupdown2.X;
                }
            }

            rreg 
=
 
new
 Rectangle(TabArea.Left, TabControlArea.Top, nWidth 

 nMargin, TabControlArea.Height);

            g.SetClip(rreg);

            
//
 draw tabs


            
for
 (
int
 i 
=
 
0
; i 
<
 
this
.TabCount; i
++
)
                DrawTab(g, 

this
.TabPages[i], i);

            g.Clip 
=
 rsaved;
            

//
—————————-

            
//
yuterz
            

//
—————————-
            

//
 draw background to cover flat border areas


            
if
 (
this
.SelectedTab 
!=
 
null
)
            {
                TabPage tabPage 

=
 
this
.SelectedTab;
                Color color 

=
 tabPage.BackColor;
                

//
border = new Pen(color);


                border 
=
 
new
 Pen(Color.Green);
                TabArea.Offset(

1

1
);
                TabArea.Width 

-=
 
2
;
                TabArea.Height 

-=
 
2
;

                
//
g.DrawRectangle(border, TabArea);


                TabArea.Width 
-=
 
1
;
                TabArea.Height 

-=
 
1
;
                

//
 g.DrawRectangle(border, TabArea);



                border.Dispose();

            }

            
//
—————————-


        }

        
internal
 
void
 DrawTab(Graphics g, TabPage tabPage, 
int
 nIndex)
        {

            Rectangle recBounds 
=
 
this
.GetTabRect(nIndex);
            RectangleF tabTextArea 

=
 (RectangleF)
this
.GetTabRect(nIndex);

            
bool
 bSelected 
=
 (
this
.SelectedIndex 
==
 nIndex);

            Point[] pt 
=
 
new
 Point[
7
];
            

if
 (
this
.Alignment 
==
 TabAlignment.Top)
            {
                pt[

0

=
 
new
 Point(recBounds.Left, recBounds.Bottom);
                pt[

1

=
 
new
 Point(recBounds.Left, recBounds.Top 
+
 
3
);
                pt[

2

=
 
new
 Point(recBounds.Left 
+
 
3
, recBounds.Top);
                pt[

3

=
 
new
 Point(recBounds.Right 

 
3
, recBounds.Top);
                pt[

4

=
 
new
 Point(recBounds.Right, recBounds.Top 
+
 
3
);
                pt[

5

=
 
new
 Point(recBounds.Right, recBounds.Bottom);
                pt[

6

=
 
new
 Point(recBounds.Left, recBounds.Bottom);
            }
            

else

            {
                pt[

0

=
 
new
 Point(recBounds.Left, recBounds.Top);
                pt[

1

=
 
new
 Point(recBounds.Right, recBounds.Top);
                pt[

2

=
 
new
 Point(recBounds.Right, recBounds.Bottom 

 
3
);
                pt[

3

=
 
new
 Point(recBounds.Right 

 
3
, recBounds.Bottom);
                pt[

4

=
 
new
 Point(recBounds.Left 
+
 
3
, recBounds.Bottom);
                pt[

5

=
 
new
 Point(recBounds.Left, recBounds.Bottom 

 
3
);
                pt[

6

=
 
new
 Point(recBounds.Left, recBounds.Top);
            }

            
//
—————————-
            

//
 fill this tab with background color
            

//
Brush br = new SolidBrush(tabPage.BackColor);


            Brush br 
=
 
new
 SolidBrush(Color.White);

            
//
—————————-

            
//
—————————-
            

//
 draw border
            

//
g.DrawRectangle(SystemPens.ControlDark, recBounds);
            

//
 g.DrawPolygon(SystemPens.ControlDark, pt);

            
//
默认的左右边框没有被选中时的标题边框颜色


            g.DrawPolygon(
new
 Pen(SkinHelp.ControlBorderBackColor), pt);

            
if
 (bSelected)
            {
                

//
—————————-
                

//
 clear bottom lines


                Pen pen 
=
 
new
 Pen(tabPage.BackColor);

                
switch
 (
this
.Alignment)
                {
                    

case
 TabAlignment.Top:
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Bottom, recBounds.Right 

 
1
, recBounds.Bottom);
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Bottom 
+
 
1
, recBounds.Right 

 
1
, recBounds.Bottom 
+
 
1
);
                        

break
;

                    
case
 TabAlignment.Bottom:
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Top, recBounds.Right 

 
1
, recBounds.Top);
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Top 

 
1
, recBounds.Right 

 
1
, recBounds.Top 

 
1
);
                        g.DrawLine(pen, recBounds.Left 

+
 
1
, recBounds.Top 

 
2
, recBounds.Right 

 
1
, recBounds.Top 

 
2
);
                        

break
;
                }

                g.FillPolygon(br, pt);
                br.Dispose();

                
//
左右被选中时颜色


                g.DrawPolygon(
new
 Pen(Color.Red), pt);
                g.DrawLine(

new
 Pen(Color.White, 2f), recBounds.Left 
+
 
1
, recBounds.Bottom 
+
 
1
, recBounds.Right 

 
1
, recBounds.Bottom 
+
 
1
);

                pen.Dispose();
                
//
—————————-


            }
            

else

            {
                

//
没有选中时的下边框颜色


                g.DrawLine(
new
 Pen(SkinHelp.ControlBorderBackColor), recBounds.Left 
+
 
1
, recBounds.Bottom, recBounds.Right 

 
1
, recBounds.Bottom);
            }

            
if
 ((tabPage.ImageIndex 
>=
 
0

&&
 (ImageList 
!=
 
null

&&
 (ImageList.Images[tabPage.ImageIndex] 
!=
 
null
))
            {
                

int
 nLeftMargin 
=
 
8
;
                

int
 nRightMargin 
=
 
2
;

                Image img 
=
 ImageList.Images[tabPage.ImageIndex];

                Rectangle rimage 
=
 
new
 Rectangle(recBounds.X 
+
 nLeftMargin, recBounds.Y 
+
 
1
, img.Width, img.Height);

                
//
 adjust rectangles


                
float
 nAdj 
=
 (
float
)(nLeftMargin 
+
 img.Width 
+
 nRightMargin);

                rimage.Y 
+=
 (recBounds.Height 

 img.Height) 
/
 
2
;
                tabTextArea.X 

+=
 nAdj;
                tabTextArea.Width 

-=
 nAdj;

                
//
 draw icon


                g.DrawImage(img, rimage);
            }

            
//
 draw string


            StringFormat stringFormat 
=
 
new
 StringFormat();
            stringFormat.Alignment 

=
 StringAlignment.Center;
            stringFormat.LineAlignment 

=
 StringAlignment.Center;

            br 
=
 
new
 SolidBrush(SkinHelp.FontColor);

            g.DrawString(tabPage.Text, Font, br, tabTextArea, stringFormat);

            
if
 (nIndex 
==
 
0
)
            {
                

//
最左上角标题上的竖线


                Pen pen 
=
 
new
 Pen(SkinHelp.ControlBorderBackColor);
                g.DrawLine(pen, 

3

5

3
, recBounds.Height 
+
 
3
);
            }
        }

        
internal
 
void
 DrawIcons(Graphics g)
        {
            

if
 ((leftRightImages 
==
 
null

||
 (leftRightImages.Images.Count 
!=
 
4
))
                

return
;

            
//
 calc positions


            Rectangle TabControlArea 
=
 
this
.ClientRectangle;

            Rectangle r0 
=
 
new
 Rectangle();
            Win32.GetClientRect(scUpDown.Handle, 

ref
 r0);

            
//
 当Tab多时背景颜色


            Brush br 
=
 
new
 SolidBrush(Color.Transparent);

            g.FillRectangle(br, r0);
            br.Dispose();

            
//
当Tab多时边框颜色


            Pen border 
=
 
new
 Pen(SkinHelp.ControlBorderBackColor);
            Rectangle rborder 

=
 
new
 Rectangle(
1

1

36

19
);
            rborder.Inflate(


1


1
);
            g.DrawRectangle(border, rborder);
            border.Dispose();

            
int
 nMiddle 
=
 (r0.Width 
/
 
2
);
            

int
 nTop 
=
 (r0.Height 

 
16

/
 
2
;
            

int
 nLeft 
=
 (nMiddle 

 
16

/
 
2
;

            Rectangle r1 
=
 
new
 Rectangle(nLeft, nTop, 
16

16
);
            Rectangle r2 

=
 
new
 Rectangle(nMiddle 
+
 nLeft, nTop, 
16

16
);

            
//
 draw buttons


            Image img 
=
 leftRightImages.Images[
1
];
            

if
 (img 
!=
 
null
)
            {
                

if
 (
this
.TabCount 
>
 
0
)
                {
                    Rectangle r3 

=
 
this
.GetTabRect(
0
);
                    

if
 (r3.Left 
<
 TabControlArea.Left)
                        g.DrawImage(img, r1);
                    

else

                    {
                        img 

=
 leftRightImages.Images[
3
];
                        

if
 (img 
!=
 
null
)
                            g.DrawImage(img, r1);
                    }
                }
            }

            img 
=
 leftRightImages.Images[
0
];
            

if
 (img 
!=
 
null
)
            {
                

if
 (
this
.TabCount 
>
 
0
)
                {
                    Rectangle r3 

=
 
this
.GetTabRect(
this
.TabCount 

 
1
);
                    

if
 (r3.Right 
>
 (TabControlArea.Width 

 r0.Width))
                        g.DrawImage(img, r2);
                    

else

                    {
                        img 

=
 leftRightImages.Images[
2
];
                        

if
 (img 
!=
 
null
)
                            g.DrawImage(img, r2);
                    }
                }
            }
        }

        
protected
 
override
 
void
 OnCreateControl()
        {
            

base
.OnCreateControl();

            
foreach
 (TabPage page 
in
 
this
.TabPages)
            {
                page.BackColor 

=
 Color.White;
            }

            FindUpDown();
        }

        
private
 
void
 FlatTabControl_ControlAdded(
object
 sender, ControlEventArgs e)
        {
            FindUpDown();
            UpdateUpDown();
        }

  
private
 
void
 FlatTabControl_ControlRemoved(
object
 sender, ControlEventArgs e)
        {
            FindUpDown();
            UpdateUpDown();
        }

        
private
 
void
 FlatTabControl_SelectedIndexChanged(
object
 sender, EventArgs e)
        {
            UpdateUpDown();
            Invalidate();    

//
 we need to update border and background colors


        }

        
private
 
void
 FindUpDown()
        {
            

bool
 bFound 
=
 
false
;

            
//
 find the UpDown control


            IntPtr pWnd 
=
 Win32.GetWindow(
this
.Handle, Win32.GW_CHILD);

            
while
 (pWnd 
!=
 IntPtr.Zero)
            {
                

//
 Get the window class name


                
char
[] className 
=
 
new
 
char
[
33
];

                
int
 length 
=
 Win32.GetClassName(pWnd, className, 
32
);

                
string
 s 
=
 
new
 
string
(className, 
0
, length);

                
if
 (s 
==
 

msctls_updown32

)
                {
                    bFound 

=
 
true
;

                    
if
 (
!
bUpDown)
                    {
                        

//
 Subclass it


                        
this
.scUpDown 
=
 
new
 SubClass(pWnd, 
true
);
                        

this
.scUpDown.SubClassedWndProc 
+=
 
new
 SubClass.SubClassWndProcEventHandler(scUpDown_SubClassedWndProc);

                        bUpDown 
=
 
true
;
                    }
                    

break
;
                }

                pWnd 
=
 Win32.GetWindow(pWnd, Win32.GW_HWNDNEXT);
            }

            
if
 ((
!
bFound) 
&&
 (bUpDown))
                bUpDown 

=
 
false
;
        }

        
private
 
void
 UpdateUpDown()
        {
            

if
 (bUpDown)
            {
                

if
 (Win32.IsWindowVisible(scUpDown.Handle))
                {
                    Rectangle rect 

=
 
new
 Rectangle();

                    Win32.GetClientRect(scUpDown.Handle, 
ref
 rect);
                    Win32.InvalidateRect(scUpDown.Handle, 

ref
 rect, 
true
);
                }
            }
        }

        
#region
 scUpDown_SubClassedWndProc Event Handler

        
private
 
int
 scUpDown_SubClassedWndProc(
ref
 Message m)
        {
            

switch
 (m.Msg)
            {
                

case
 Win32.WM_PAINT:
                    {
                        

//
 redraw


                        IntPtr hDC 
=
 Win32.GetWindowDC(scUpDown.Handle);
                        Graphics g 

=
 Graphics.FromHdc(hDC);

                        DrawIcons(g);

                        g.Dispose();
                        Win32.ReleaseDC(scUpDown.Handle, hDC);

                        
//
 return 0 (processed)


                        m.Result 
=
 IntPtr.Zero;

                        
//
 validate current rect


                        Rectangle rect 
=
 
new
 Rectangle();

                        Win32.GetClientRect(scUpDown.Handle, 
ref
 rect);
                        Win32.ValidateRect(scUpDown.Handle, 

ref
 rect);
                    }
                    

return
 
1
;
            }

            
return
 
0
;
        }
        

#endregion

        
///
 
<summary>

        

///
 重新设置边框
        

///
 
</summary>

        

///
 
<param name=”m”>
当前的Windows消息
</param>


        
protected
 
override
 
void
 WndProc(
ref
 Message m)
        {
            

base
.WndProc(
ref
 m);
            

if
 (m.Msg 
==
 
0xf
 
||
 m.Msg 
==
 
0x133
)
            {
                SkinHelp.ResetBorderColor(m, 

this

1
, SkinHelp.Defalutborder);
            }
        }

        
#region
 Component Designer generated code

        

///
 
<summary>

        

///
 Required method for Designer support – do not modify 
        

///
 the contents of this method with the code editor.
        

///
 
</summary>


        
private
 
void
 InitializeComponent()
        {
            components 

=
 
new
 System.ComponentModel.Container();
        }

        
#endregion

        
#region
 Properties

        [Editor(
typeof
(TabpageExCollectionEditor), 
typeof
(UITypeEditor))]
        

public
 
new
 TabPageCollection TabPages
        {
            

get

            {
                

return
 
base
.TabPages;
            }
        }

        
new
 
public
 TabAlignment Alignment
        {
            

get
 { 
return
 
base
.Alignment; }
            

set

            {
                TabAlignment ta 

=
 value;
                

if
 ((ta 
!=
 TabAlignment.Top) 
&&
 (ta 
!=
 TabAlignment.Bottom))
                    ta 

=
 TabAlignment.Top;

                
base
.Alignment 
=
 ta;
            }
        }

        [Browsable(
false
)]
        

new
 
public
 
bool
 Multiline
        {
            

get
 { 
return
 
base
.Multiline; }
            

set
 { 
base
.Multiline 
=
 
false
; }
        }

        [Browsable(
true
)]
        

new
 
public
 Color myBackColor
        {
            

get
 { 
return
 mBackColor; }
            

set
 { mBackColor 
=
 value; 
this
.Invalidate(); }
        }

        
#endregion

        
#region
 TabpageExCollectionEditor

        
internal
 
class
 TabpageExCollectionEditor : CollectionEditor
        {
            

public
 TabpageExCollectionEditor(System.Type type)
                : 

base
(type)
            {
            }

            
protected
 
override
 Type CreateCollectionItemType()
            {
                

return
 
typeof
(TabPage);
            }
        }

        
#endregion

    }
}