1

I have create a custom OwnerDraw inherited ToolTip control into a Class and I have a size issue. If text is too long I "lose" last characters. Depends on how long the text is. I have try several things but I can't imagine what can be wrong. Any kind of help would be really helpful.

Imports System.Windows.Forms
Imports System.ComponentModel

Public Class Form_CustomToolTip
    Inherits ToolTip

    Public Sub New()
        Me.Active = True
        Me.AlignHorizontal = StringAlignment.Center
        Me.AlignVertical = StringAlignment.Center
        Me.AutomaticDelay = 100
        Me.AutoPopDelay = 1000000
        Me.BackColor = Color.White
        Me.BorderColor_UL = Color.Black
        Me.BorderColor_BR = Color.Black
        Me.Font = New Font("Microsoft Sans Serif", 8.25!)
        Me.ForeColor = Color.Black
        Me.InitialDelay = 100
        Me.OwnerDraw = True
        Me.ReshowDelay = 100
        Me.ShowAlways = False
        Me.StripAmpersands = False
        Me.Tag = ""
        Me.UseAnimation = True
        Me.UseFading = True
    End Sub

    '((( EVENTS )))
    Private Sub Form_CustomToolTip_Popup(sender As Object, e As System.Windows.Forms.PopupEventArgs) Handles Me.Popup
        Dim _Font As Font = sender.Font
        e.ToolTipSize = TextRenderer.MeasureText(sender.GetToolTip(e.AssociatedWindow), _Font)
    End Sub
    Private Sub Form_CustomToolTip_Draw(sender As System.Object, e As DrawToolTipEventArgs) Handles Me.Draw
        '((( Draw the custom background. ))) ((( For standard background use "e.DrawBackground()". ())))
        Dim _BackColor = New SolidBrush(sender.Backcolor)
        e.Graphics.FillRectangle(_BackColor, e.Bounds)
        '((( Draw the custom borders. ))) ((( For standard borders use "e.DrawBorder()" )))
        Dim _BorderColor_UL As Color = sender.BorderColor_UL
        e.Graphics.DrawLines(
            New Pen(_BorderColor_UL),
            New Point() {New Point(0, e.Bounds.Height - 1), New Point(0, 0), New Point(e.Bounds.Width - 1, 0)}
        )
        Dim _BorderColor_BR As Color = sender.BorderColor_BR
        e.Graphics.DrawLines(
            New Pen(_BorderColor_BR),
            New Point() {New Point(0, e.Bounds.Height - 1), New Point(e.Bounds.Width - 1, e.Bounds.Height - 1), New Point(e.Bounds.Width - 1, 0)}
        )
        '((( Draw the custom text. ))) ((( For Standard text use "e.DrawText()". )))
        Dim _AlignHorizontal As StringAlignment = sender.AlignHorizontal
        Dim _AlignVertical As StringAlignment = sender.AlignVertical
        Dim _StringFormat As StringFormat = New StringFormat With {
            .Alignment = _AlignHorizontal,
            .LineAlignment = _AlignVertical,
            .HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide,
            .FormatFlags = StringFormatFlags.NoWrap
        }
        Dim _Font As Font = sender.Font
        Dim _ForeColor As New SolidBrush(sender.Forecolor)
        e.Graphics.DrawString(e.ToolTipText, _Font, _ForeColor, RectangleF.op_Implicit(e.Bounds), _StringFormat)
    End Sub

    '((( CUSTOM PROPERTIES )))
    Private _Border_Color_UL As Color
    <Category("Custom Properties")> <DisplayName("Border Color UL")> <Description("The color for up and left borders.")>
    Public Property BorderColor_UL As Color
        Get
            Return _Border_Color_UL
        End Get
        Set(ByVal Value As Color)
            _Border_Color_UL = Value
        End Set
    End Property
    Private _BorderColor_BR As Color
    <Category("Custom Properties")> <DisplayName("Border Color BR")> <Description("The color for bottom and right borders.")>
    Public Property BorderColor_BR As Color
        Get
            Return _BorderColor_BR
        End Get
        Set(ByVal Value As Color)
            _BorderColor_BR = Value
        End Set
    End Property
    Private _Font As Font
    <Category("Custom Properties")> <DisplayName("Font")> <Description("The font used to display ToolTip's text.")>
    Public Property Font As Font
        Get
            Return _Font
        End Get
        Set(ByVal Value As Font)
            _Font = Value
        End Set
    End Property
    Private _AlignVertical As StringAlignment
    <Category("Custom Properties")> <DisplayName("Align Vertical")> <Description("ToolTip's text vertical align.")>
    Public Property AlignVertical As StringAlignment
        Get
            Return _AlignVertical
        End Get
        Set(ByVal Value As StringAlignment)
            _AlignVertical = Value
        End Set
    End Property
    Private _AlignHorizontal As StringAlignment
    <Category("Custom Properties")> <DisplayName("Align Horizontal")> <Description("ToolTip's text horizontal align.")>
    Public Property AlignHorizontal As StringAlignment
        Get
            Return _AlignHorizontal
        End Get
        Set(ByVal Value As StringAlignment)
            _AlignHorizontal = Value
        End Set
    End Property

    '((( DISABLED PROPERTIES )))
    <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)>
    Public Overloads Property IsBalloon As Boolean
    <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)>
    Public Overloads Property ToolTipIcon As ToolTipIcon
    <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)>
    Public Overloads Property ToolTipTitle As String

End Class
Simos Sigma
  • 958
  • 7
  • 29
  • 1
    First, and most importantly, set `Option Strict On`. Always. Turn it on and rip off the knob. I started to delve into it, but there are too many compiler errors. Start with the way you measure and draw. You use TextRenderer to measure the text, but then use `Graphics.DrawString` to draw the text (vs `TextRenderer.DrawText`). The measurements are not exact, so you will have to add a fudge factor in addition to any border/margin/gutter you want to provide. **[Option Strict](https://stackoverflow.com/a/43531217/1070452)** – Ňɏssa Pøngjǣrdenlarp Mar 09 '18 at 18:07
  • @Plutonix: Thank you for your valuable advices my friend!!! – Simos Sigma Mar 09 '18 at 21:12

1 Answers1

1

Try giving your measurement a padding:

Private Sub Form_CustomToolTip_Popup(sender As Object, e As PopupEventArgs) Handles Me.Popup
  Dim toolSize As Size = TextRenderer.MeasureText(Me.GetToolTip(e.AssociatedWindow), Me.Font)
  toolSize.Width += 16
  toolSize.Height += 10
  e.ToolTipSize = toolSize
End Sub

Then when you draw it, favor using TextRenderer instead:

TextRenderer.DrawText(e.Graphics, e.ToolTipText, Me.Font, e.Bounds, 
                      Me.ForeColor, Color.Empty,
                      TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter)
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • 1
    @SimonetosTheGreek You're welcome. Don't ignore the advice from Plutonix, as well as, learn to dispose your drawing objects. Pens, Brushes all need to be disposed. – LarsTech Mar 09 '18 at 19:57
  • 1
    No, I will not ignore his advice for sure!!! I have already enable `Option Strict On` at my whole project and I began to corect things. – Simos Sigma Mar 09 '18 at 21:02
  • When you say that I should dispose my drawing objects, do you mean something like that ( https://msdn.microsoft.com/en-us/library/system.drawing.graphics.dispose(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1 )? – Simos Sigma Mar 09 '18 at 21:31
  • 1
    @SimonetosTheGreek Yes, or in a Using ... End Using block. – LarsTech Mar 09 '18 at 21:32