C# WinC窗体中的TabControl绘制和边界#

C# WinC窗体中的TabControl绘制和边界#,c#,winforms,custom-controls,C#,Winforms,Custom Controls,我使用了一个由其他帖子创建的自定义控件。我试图修改它,以适应我的要求,但我被困在那些领域,我们无法编辑它 这是我修改过的控制代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks

我使用了一个由其他帖子创建的自定义控件。我试图修改它,以适应我的要求,但我被困在那些领域,我们无法编辑它

这是我修改过的控制代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CControls
{
public partial class TapControl : TabControl
{

    #region "Properties"
    private int _hotTabIndex = -1;
    private int HotTabIndex
    {
        get { return _hotTabIndex; }
        set
        {
            if (_hotTabIndex != value)
            {
                _hotTabIndex = value;
                this.Invalidate();
            }
        }
    }

    private int CloseButtonHeight
    {
        get { return FontHeight; }
    }

    #endregion

    public TapControl()
    {
        InitializeComponent();
        this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);

        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.ResizeRedraw, true);
        this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

        this.DrawMode = TabDrawMode.OwnerDrawFixed;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.DrawLine(Pens.White, 0, 0, ClientRectangle.Right,ClientRectangle.Top);
        e.Graphics.DrawLine(Pens.Red, 0, ItemSize.Height+2, ClientRectangle.Right-1, ItemSize.Height+2);
        base.OnPaint(e);

        for (int id = 0; id < this.TabCount; id++)
            DrawTabContent(e.Graphics, id);
    }


    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        base.OnPaintBackground(pevent);
        for (int id = 0; id < this.TabCount; id++)
            DrawTabBackground(pevent.Graphics, id);
    }

    protected override void OnCreateControl()
    {
        base.OnCreateControl();
        this.OnFontChanged(EventArgs.Empty);
    }

    protected override void OnFontChanged(EventArgs e)
    {
        base.OnFontChanged(e);
        IntPtr hFont = this.Font.ToHfont();
        SendMessage(this.Handle, WM_SETFONT, hFont, new IntPtr(-1));
        SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
        this.UpdateStyles();
    }


    private void DrawTabContent(Graphics graphics, int id)
    {
        bool selectedOrHot = id == this.SelectedIndex || id == this.HotTabIndex;
        bool vertical = this.Alignment >= TabAlignment.Left;

        Image tabImage = null;

        if (this.ImageList != null)
        {
            TabPage page = this.TabPages[id];
            if (page.ImageIndex > -1 && page.ImageIndex < this.ImageList.Images.Count)
                tabImage = this.ImageList.Images[page.ImageIndex];

            if (page.ImageKey.Length > 0 && this.ImageList.Images.ContainsKey(page.ImageKey))
                tabImage = this.ImageList.Images[page.ImageKey];
        }

        Rectangle tabRect = GetTabRect(id);
        Rectangle contentRect = vertical ? new Rectangle(0, 0, tabRect.Height, tabRect.Width) : new Rectangle(Point.Empty, tabRect.Size);
        contentRect = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ItemSize.Width, ItemSize.Height);
        Rectangle textrect = contentRect;
        textrect.Width -= FontHeight;

        if (tabImage != null)
        {
            textrect.Width -= tabImage.Width;
            textrect.X += tabImage.Width;
        }


        Color frColor = id == SelectedIndex ? Color.Black : this.ForeColor;
        Color bkColor = id == SelectedIndex ? Color.White : FindForm().BackColor;

        using (Bitmap bm = new Bitmap(contentRect.Width, contentRect.Height))
        {
            using (Graphics bmGraphics = Graphics.FromImage(bm))
            {
                TextRenderer.DrawText(bmGraphics, this.TabPages[id].Text, this.Font, textrect, frColor, bkColor);
                //if (selectedOrHot)
                //{
                    Rectangle closeRect = new Rectangle(contentRect.Right - CloseButtonHeight, 0, CloseButtonHeight, CloseButtonHeight);
                    closeRect.Offset(-2, (contentRect.Height - closeRect.Height) / 2);
                    DrawCloseButton(bmGraphics, closeRect);
                //}
                if (tabImage != null)
                {
                    Rectangle imageRect = new Rectangle(Padding.X, 0, tabImage.Width, tabImage.Height);
                    imageRect.Offset(0, (contentRect.Height - imageRect.Height) / 2);
                    bmGraphics.DrawImage(tabImage, imageRect);
                }
            }

            if (vertical)
            {
                if (this.Alignment == TabAlignment.Left)
                    bm.RotateFlip(RotateFlipType.Rotate270FlipNone);
                else
                    bm.RotateFlip(RotateFlipType.Rotate90FlipNone);
            }
            graphics.DrawImage(bm, tabRect);

        }
    }

    private void DrawCloseButton(Graphics graphics, Rectangle bounds)
    {
        using (Font closeFont = new Font("Tahoma", Font.Size, FontStyle.Bold))
            TextRenderer.DrawText(graphics, "x", closeFont, bounds, Color.Gray, Color.Transparent, TextFormatFlags.HorizontalCenter | TextFormatFlags.NoPadding | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter);

    }



    private void DrawTabBackground(Graphics graphics, int id)
    {
        if (id == SelectedIndex)
            graphics.FillRectangle(Brushes.White, GetTabRect(id));
        else if (id == HotTabIndex)
        {
            Rectangle rc = GetTabRect(id);
            rc.Width--;
            rc.Height--;
            graphics.DrawRectangle(Pens.DarkGray, rc);
        }
    }


    private const int TCM_ADJUSTRECT = 0x1328;//(TCM_FIRST + 40);
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == TCM_SETPADDING)
        {
            m.LParam = MAKELPARAM(this.Padding.X + CloseButtonHeight / 2, this.Padding.Y);
        }

        if (m.Msg == WM_MOUSEDOWN && !this.DesignMode)
        {
            Point pt = this.PointToClient(Cursor.Position);
            Rectangle closeRect = GetCloseButtonRect(HotTabIndex);
            if (closeRect.Contains(pt) && HotTabIndex != 0)
            {
                TabPages.RemoveAt(HotTabIndex);
                m.Msg = WM_NULL;
            }
        }

        if (m.Msg == TCM_ADJUSTRECT && !this.DesignMode)
        {
            RECT rc = new RECT();
            rc.Left -= 3;
            rc.Right += 1;
            rc.Top -= 1;
            rc.Bottom += 1;
            Marshal.StructureToPtr(rc, m.LParam, true);
        }

        base.WndProc(ref m);
    }
    private struct RECT{
        public int Left, Top, Right, Bottom;
    }







    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        TCHITTESTINFO HTI = new TCHITTESTINFO(e.X, e.Y);
        HotTabIndex = SendMessage(this.Handle, TCM_HITTEST, IntPtr.Zero, ref HTI);
    }

    protected override void OnMouseLeave(EventArgs e)
    {
        base.OnMouseLeave(e);
        HotTabIndex = -1;
    }







    private IntPtr MAKELPARAM(int lo, int hi)
    {
        return new IntPtr((hi << 16) | (lo & 0xFFFF));
    }

    private Rectangle GetCloseButtonRect(int id)
    {

        Rectangle tabRect = GetTabRect(id);
        Rectangle closeRect = new Rectangle(tabRect.Left, tabRect.Top, CloseButtonHeight, CloseButtonHeight);

        switch (Alignment)
        {
            case TabAlignment.Left:
                closeRect.Offset((tabRect.Width - closeRect.Width) / 2, 0);
                break;
            case TabAlignment.Right:
                closeRect.Offset((tabRect.Width - closeRect.Width) / 2, tabRect.Height - closeRect.Height);
                break;
            default:
                closeRect.Offset(tabRect.Width - closeRect.Width, (tabRect.Height - closeRect.Height) / 2);
                break;
        }

        return closeRect;
    }




    #region Interop

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, ref TCHITTESTINFO lParam);

    [StructLayout(LayoutKind.Sequential)]
    private struct TCHITTESTINFO
    {
        public Point pt;
        public TCHITTESTFLAGS flags;
        public TCHITTESTINFO(int x, int y)
        {
            pt = new Point(x, y);
            flags = TCHITTESTFLAGS.TCHT_NOWHERE;
        }
    }

    [Flags()]
    private enum TCHITTESTFLAGS
    {
        TCHT_NOWHERE = 1,
        TCHT_ONITEMICON = 2,
        TCHT_ONITEMLABEL = 4,
        TCHT_ONITEM = TCHT_ONITEMICON | TCHT_ONITEMLABEL
    }

    private const int WM_NULL = 0x0;
    private const int WM_SETFONT = 0x30;
    private const int WM_FONTCHANGE = 0x1D;
    private const int WM_MOUSEDOWN = 0x201;

    private const int TCM_FIRST = 0x1300;
    private const int TCM_HITTEST = TCM_FIRST + 13;
    private const int TCM_SETPADDING = TCM_FIRST + 43;

    #endregion

}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统图;
使用系统数据;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
命名空间cControl
{
公共部分类TapControl:TabControl
{
#区域“财产”
私有int_hottab index=-1;
私有int HotTabIndex
{
获取{return\u hottab index;}
设置
{
if(_hotTabIndex!=值)
{
_hotTabIndex=值;
这个。使无效();
}
}
}
私人内特封闭式按钮灯
{
获取{return FontHeight;}
}
#端区
公共交通管制(
{
初始化组件();
此.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizerDraw | ControlStyles.UserPaint,true);
this.SetStyle(ControlStyles.UserPaint,true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer,true);
this.SetStyle(ControlStyles.ResizerDraw,true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor,true);
this.DrawMode=TabDrawMode.OwnerDrawFixed;
}
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
e、 图形。抽绳(钢笔。白色,0,0,ClientRectangle。右侧,ClientRectangle。顶部);
e、 图形.抽绳(Pens.Red,0,ItemSize.Height+2,ClientRectangle.Right-1,ItemSize.Height+2);
基础漆(e);
for(int id=0;id=TabAlignment.Left;
图像选项卡Image=null;
如果(this.ImageList!=null)
{
TabPage=this.TabPages[id];
如果(page.ImageIndex>-1&&page.ImageIndex0&&this.ImageList.Images.ContainsKey(page.ImageKey))
tabImage=this.ImageList.Images[page.ImageKey];
}
矩形tabRect=GetTabRect(id);
矩形contentRect=vertical?新矩形(0,0,tabRect.Height,tabRect.Width):新矩形(Point.Empty,tabRect.Size);
contentRect=新矩形(ClientRectangle.X、ClientRectangle.Y、ItemSize.Width、ItemSize.Height);
矩形textrect=contentRect;
textrect.Width-=字体高度;
if(tabImage!=null)
{
textrect.Width-=tabImage.Width;
textrect.X+=tabImage.Width;
}
Color frColor=id==SelectedIndex?Color.Black:this.ForeColor;
Color bkColor=id==SelectedIndex?Color.White:FindForm().BackColor;
使用(位图bm=新位图(contentRect.Width、contentRect.Height))
{
使用(Graphics bmGraphics=Graphics.FromImage(bm))
{
textrender.DrawText(bmGraphics,this.TabPages[id].Text,this.Font,textrect,frColor,bkColor);
//如果(选择了Rhot)
//{
矩形closeRect=新矩形(contentRect.Right-CloseButtonHeight,0,CloseButtonHeight,CloseButtonHeight);
closeRect.Offset(-2,(contentRect.Height-closeRect.Height)/2);
DrawCloseButton(bmGraphics,closeRect);
//}
if(tabImage!=null)
{
矩形imageRect=新矩形(Padding.X,0,tabImage.Width,tabImage.Height);
imageRect.Offset(0,(contentRect.Height-imageRect.Height)/2);
bmGraphics.DrawImage(tabImage,imageRect);
}
}
如果(垂直)
{
if(this.Alignment==TabAlignment.Left)
bm.RotateFlip(RotateFlipType.Rotate270FlipNone);
其他的
bm.RotateFlip(RotateFlipType.Rotate90FlipNone);
}
graphics.DrawImage(bm,tabRect);
}
}
专用void DrawCloseButton(图形、矩形边框)
{
使用(Font closeFont=新字体(“Tahoma”,Font.Size,FontStyle.Bold))
TextRenderer.DrawText(图形,“x”,闭合字体,边界,颜色。灰色,颜色。透明,TextFormatFlags.HorizontalCenter | TextFormatFlags.NoPadding | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter);
}
私有void DrawTabBackground(图形,int-id)
{
如果(id==SelectedIndex)
graphics.FillRectangle(画笔.White,GetTabRect(id));
else if(id==hottab索引)
{
矩形rc=GetTabRect(id);
rc.Width--;
rc.高度--;
图形.绘图矩形(Pens.DarkG)