Scrolling the TextBox Control to Top or Bottom

When using a textbox or richtextbox control for displaying logging information, it is useful to scroll the recently added line into view. There are two ways to accomplish this (the first solution will also work with textbox controls and supports scrolling to the top too).

Vertical scrolling only works with multi-line textboxes (the MultiLine property must be set to True), and horizontal scrolling requires the WordWrap property to be set to False:

Friend Module TextBoxExtensions
    Private Const WM_VSCROLL As Int32 = &H115
    Private Const WH_HSCROLL As Int32 = &H114

    Private Const SB_TOP As Int32 = 6
    Private Const SB_LEFT As Int32 = 6
    Private Const SB_BOTTOM As Int32 = 7
    Private Const SB_RIGHT As Int32 = 7

    Private Declare Auto Function SendMessage Lib "user32.dll" ( _
        ByVal hwnd As IntPtr, _
        ByVal wMsg As Int32, _
        ByVal wParam As IntPtr, _
        ByVal lParam As IntPtr _
    ) As IntPtr

    <Extension()> _
    Public Sub ScrollToTop(ByVal TextBox As TextBoxBase)
        SendMessage( _
            TextBox.Handle, _
            WM_VSCROLL, _
            New IntPtr(SB_TOP), _
            IntPtr.Zero _
        )
    End Sub

    <Extension()> _
    Public Sub ScrollToLeft(ByVal TextBox As TextBoxBase)
        SendMessage( _
            TextBox.Handle, _
            WH_HSCROLL, _
            New IntPtr(SB_LEFT), _
            IntPtr.Zero _
        )
    End Sub

    <Extension()> _
    Public Sub ScrollToBottom(ByVal TextBox As TextBoxBase)
        SendMessage( _
            TextBox.Handle, _
            WM_VSCROLL, _
            New IntPtr(SB_BOTTOM), _
            IntPtr.Zero _
        )
    End Sub

    <Extension()> _
    Public Sub ScrollToRight(ByVal TextBox As TextBoxBase)
        SendMessage( _
            TextBox.Handle, _
            WH_HSCROLL, _
            New IntPtr(SB_RIGHT), _
            IntPtr.Zero _
        )
    End Sub
End Module

Usage:

With Me.TextBox1
    .AppendText("Hello World")
    .ScrollToBottom()
End With

— or —

The richtextbox control provides a ScrollToCaret method that can be used to scroll the control to the caret position. However, this approach might have side-effects because setting the focus to the control may raise validation events:

Dim LastActiveControl As Control = Me.ActiveControl
With Me.RichTextBox1
    .Focus()
    .AppendText("Hello World!")
    .ScrollToCaret()
End With
LastActiveControl.Focus()