1

I'm trying to make a custom TabControl Owner Draw but the tab didn't expand properly. How I supposed to do that? Set TabPage Width/Height didn't help. I'm not sure if I'm calculating the locations properly. How do I fix this? the image look like this:

enter image description here

the code to draw it look like this:

    private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
    {
        var tabPage = this.tabControl1.TabPages[e.Index];
        var tabRect = this.tabControl1.GetTabRect(e.Index);
        tabRect.Inflate(-2, -2);
        if (e.Index == this.tabControl1.TabCount - 1)
        {
            var addImage = Properties.Resources.Add;
            e.Graphics.DrawImage(addImage,
                tabRect.Left + (tabRect.Width - addImage.Width) / 2,
                tabRect.Top + (tabRect.Height - addImage.Height) / 2);
        }
        else
        {
            var icon = Properties.Resources.apple_icon;
            e.Graphics.DrawImage(icon, tabRect.X, tabRect.Y);

            var closeImage = Properties.Resources.Close;
            e.Graphics.DrawImage(closeImage,
                (tabRect.Right - closeImage.Width),
                tabRect.Top + (tabRect.Height - closeImage.Height) / 2);
            var rect = new Rectangle(tabRect.X + icon.Width,
                      tabRect.Y,
                      tabRect.Width,
                      tabRect.Height);
            TextRenderer.DrawText(e.Graphics, tabPage.Text, tabPage.Font,
                rect, tabPage.ForeColor, TextFormatFlags.Left);
        }
    }

full code look like this:

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.tabControl1.TabPages[this.tabControl1.TabCount - 1].Text = "";
            this.tabControl1.Padding = new Point(12, 4);
            this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;

            this.tabControl1.DrawItem += tabControl1_DrawItem;
            this.tabControl1.MouseDown += tabControl1_MouseDown;
            this.tabControl1.Selecting += tabControl1_Selecting;
            this.tabControl1.HandleCreated += tabControl1_HandleCreated;
        }
        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
        private const int TCM_SETMINTABWIDTH = 0x1300 + 49;
        private void tabControl1_HandleCreated(object sender, EventArgs e)
        {
            SendMessage(this.tabControl1.Handle, TCM_SETMINTABWIDTH, IntPtr.Zero, (IntPtr)16);
        }
        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (e.TabPageIndex == this.tabControl1.TabCount - 1)
                e.Cancel = true;
        }
        private void tabControl1_MouseDown(object sender, MouseEventArgs e)
        {
            var lastIndex = this.tabControl1.TabCount - 1;
            if (this.tabControl1.GetTabRect(lastIndex).Contains(e.Location))
            {
                this.tabControl1.TabPages.Insert(lastIndex, "New Tab");
                this.tabControl1.SelectedIndex = lastIndex;
                this.tabControl1.TabPages[lastIndex].UseVisualStyleBackColor=true;
            }
            else
            {
                for (var i = 0; i < this.tabControl1.TabPages.Count; i++)
                {
                    var tabRect = this.tabControl1.GetTabRect(i);
                    tabRect.Inflate(-2, -2);
                    var closeImage = Properties.Resources.Close;
                    var imageRect = new Rectangle(
                        (tabRect.Right - closeImage.Width),
                        tabRect.Top + (tabRect.Height - closeImage.Height) / 2,
                        closeImage.Width,
                        closeImage.Height);
                    if (imageRect.Contains(e.Location))
                    {
                        this.tabControl1.TabPages.RemoveAt(i);
                        break;
                    }
                }
            }
        }
        private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
        {
            var tabPage = this.tabControl1.TabPages[e.Index];
            var tabRect = this.tabControl1.GetTabRect(e.Index);
            tabRect.Inflate(-2, -2);
            if (e.Index == this.tabControl1.TabCount - 1)
            {
                var addImage = Properties.Resources.Add;
                e.Graphics.DrawImage(addImage,
                    tabRect.Left + (tabRect.Width - addImage.Width) / 2,
                    tabRect.Top + (tabRect.Height - addImage.Height) / 2);
            }
            else
            {
                var icon = Properties.Resources.apple_icon;
                e.Graphics.DrawImage(icon, tabRect.X, tabRect.Y);

                var closeImage = Properties.Resources.Close;
                e.Graphics.DrawImage(closeImage,
                    (tabRect.Right - closeImage.Width),
                    tabRect.Top + (tabRect.Height - closeImage.Height) / 2);
                var rect = new Rectangle(tabRect.X + icon.Width,
                          tabRect.Y,
                          tabRect.Width,
                          tabRect.Height);
                TextRenderer.DrawText(e.Graphics, tabPage.Text, tabPage.Font,
                    rect, tabPage.ForeColor, TextFormatFlags.Left);
            }
        }
    }

The original code was taken from this answer

Andy
  • 12,859
  • 5
  • 41
  • 56
Neto Dll
  • 11
  • 1
  • For some reason I can't add a image to my question, I'm getting a link the the image instead of. What am I missing?[ – Neto Dll Dec 01 '21 at 20:59
  • Did you look into the `DrawItemEventArgs e`properties? – TaW Dec 01 '21 at 21:40
  • 1
    It looks fine, the tab just isn't wide enough to display the text without overlap. Increase the Padding property of the TabControl to get more space. – Hans Passant Dec 01 '21 at 22:36
  • Maybe try increasing the value in the `TCM_SETMINTABWIDTH` call. – Andy Dec 02 '21 at 00:53
  • Increase the `Padding.X` as mentioned or try the `SizeMode = TabSizeMode.Fixed` with the `ItemSize` property. Create the `addImage`, `icon`, and `closeImage` in `using` blocks. They should be disposed of. – dr.null Dec 02 '21 at 01:07
  • @TaW what did you mean? I'm using it in the `DrawItem` event – Neto Dll Dec 02 '21 at 01:34
  • @HansPassant Just increasing the padding made it work lol I thought the math was off. Thanks! post as answer so I can accept – Neto Dll Dec 02 '21 at 01:34
  • 1
    @dr.null I did increase as Hans Passant mentioned, works like a charm. Thanks for remember to use `using`! – Neto Dll Dec 02 '21 at 01:36
  • @Andy Thank you for your input too, increased the padding and that was enough ;) – Neto Dll Dec 02 '21 at 01:37

0 Answers0