Drawing Textbox at runtime in VB.net and indexing

You can try a resizable UserControl.

Create a new UserControl as a template (German, but you will find it):

enter image description here

Set the BorderStyle to FixedSingle.

Add a Label to the UserControl. I called it lblInner:

enter image description here

Now for some coding including the possibility to resize the UserControl at Runtime using Mouse Handles. Please note that the code for resizing is used from the following excellent Stack Overflow answer by Charles P.:

Custom Resize Handle in Border-less Form C#

Public Class MyBoxLabel

#Region "Constructor"
    Public Sub New()

        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.


        Me.lblInner.AutoSize = False
        Me.lblInner.TextAlign = ContentAlignment.MiddleCenter
        'Need a free border at the sides, or the mouse actions will not work properly
        Me.lblInner.Location = New Point(3, 3)
        Me.lblInner.Size = New Size(Me.ClientSize.Width - 7, Me.ClientSize.Height - 7)
        Me.lblInner.Anchor = AnchorStyles.Left Or AnchorStyles.Bottom Or AnchorStyles.Right Or AnchorStyles.Top
    End Sub
#End Region

#Region "Properties"
    ''' <summary>
    ''' Allows you to change the inner text
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property InnerText As String
        Set(value As String)
            Me.lblInner.Text = value
        End Set
        Get
            Return Me.lblInner.Text
        End Get
    End Property

    ''' <summary>
    ''' Allows you to change the inner font
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property InnerFont As Font
        Set(value As Font)
            Me.lblInner.Font = value
        End Set
        Get
            Return Me.lblInner.Font
        End Get
    End Property

    'Add further properties as needed
#End Region

#Region "Constants"
    Const WM_NCHITTEST As UInt32 = &H84
    Const WM_MOUSEMOVE As UInt32 = &H200

    Const HTLEFT As UInt32 = 10
    Const HTRIGHT As UInt32 = 11
    Const HTBOTTOMRIGHT As UInt32 = 17
    Const HTBOTTOM As UInt32 = 15
    Const HTBOTTOMLEFT As UInt32 = 16
    Const HTTOP As UInt32 = 12
    Const HTTOPLEFT As UInt32 = 13
    Const HTTOPRIGHT As UInt32 = 14

    Const RESIZE_HANDLE_SIZE As Integer = 10
#End Region

#Region "Handling of Window Messages to allow resizing of the UserControl"
    Protected Overrides Sub WndProc(ByRef m As Message)

        Dim handled As Boolean = False
        If m.Msg = WM_NCHITTEST OrElse m.Msg = WM_MOUSEMOVE Then
            Dim formSize As Size = Me.Size
            Dim screenPoint As New Point(m.LParam.ToInt32())
            Dim clientPoint As Point = Me.PointToClient(screenPoint)

            Dim boxes As New Dictionary(Of UInt32, Rectangle)() From { _
                {HTBOTTOMLEFT, New Rectangle(0, formSize.Height - RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)}, _
                {HTBOTTOM, New Rectangle(RESIZE_HANDLE_SIZE, formSize.Height - RESIZE_HANDLE_SIZE, formSize.Width - 2 * RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)}, _
                {HTBOTTOMRIGHT, New Rectangle(formSize.Width - RESIZE_HANDLE_SIZE, formSize.Height - RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)}, _
                {HTRIGHT, New Rectangle(formSize.Width - RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, formSize.Height - 2 * RESIZE_HANDLE_SIZE)}, _
                {HTTOPRIGHT, New Rectangle(formSize.Width - RESIZE_HANDLE_SIZE, 0, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)}, _
                {HTTOP, New Rectangle(RESIZE_HANDLE_SIZE, 0, formSize.Width - 2 * RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)}, _
                {HTTOPLEFT, New Rectangle(0, 0, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)}, _
                {HTLEFT, New Rectangle(0, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, formSize.Height - 2 * RESIZE_HANDLE_SIZE)} _
            }

            For Each hitBox As KeyValuePair(Of UInt32, Rectangle) In boxes
                If hitBox.Value.Contains(clientPoint) Then
                    m.Result = CType(hitBox.Key, IntPtr)
                    handled = True
                    Exit For
                End If
            Next
        End If

        If Not handled Then
            MyBase.WndProc(m)
        End If
    End Sub
#End Region

End Class

Compile your project.

In your ToolBox you will now find the new UserControl. Add it to your form and launch your application. When you move your mouse to the edges of the control you will see the typical resize mouse cursors. Use these to resize the control. The text will stay centered due to the Anchor properties of the Label and the TextAlign.

Leave a Comment