How do I figure out the anchor and active ends of the current selection of a TextBox or RichTextBox?

RobertAlanGustafsonII

Active member
Joined
Sep 16, 2023
Messages
30
Programming Experience
10+
WHAT I HAVE:
Visual Basic 2019, .NET Framework, WinForms

MY ISSUE:
I'd like to be able to programmatically figure out which end of a selection is the anchor and which is the active end when the user changes the selection of a TextBox or RichTextBox. The SelectionStart property is always the left end of a selection, and apparently EM_GETSEL always returns left/right, whereas EM_SETSEL sets anchor/active end. Left always comes before right, but the anchor can be after the active end. This matters if one has to temporarily change, then restore the selection programatically--as the user can thus find oneself extending the selection on the left, then suddenly contracting it on the right for no apparent reason!

The following StackOverflow page provided a supposed "kludge" fix in C++ and Delphi: "EM_GETSEL swaps parameters", but I haven't been able to successfully adapt the code there to VB.NET. The following code below always sets the Active end--and the caret (with no subsequent selection)--to the end of the full text:

Anchor and active ends of selection:
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Public Shared Function SendMessage(hWnd As IntPtr, msg As Integer, ByRef wParam As Integer, _
        ByRef lParam As Integer) As IntPtr
End Function

Public Sub GetEnds(ByRef Anchor As Integer, ByRef Active As Integer)
        '   get anchor and active end of selection
        Const EM_GETSEL = &HB0, EM_SETSEL = &HB1
        Anchor = 0 : Active = 0
        Dim Start As Integer = 0, Finish As Integer = 0
        With TextBoxOrRichTextBox
            '    get ends of selection
            SendMessage(.Handle, EM_GETSEL, Start, Finish)
            '   temporarily kill selection to get active end
            SendMessage(.Handle, EM_SETSEL, -1, 0)
            SendMessage(.Handle, EM_GETSEL, Active, 0)
            '   restore selection and return values
            If Active = Start Then
                Anchor = Finish : SendMessage(.Handle, EM_SETSEL, Finish, Start)
             Else
                Anchor = Start : SendMessage(.Handle, EM_SETSEL, Start, Finish)
            End If
        End With
End Sub

I need a solution quickly. Please respond ASAP--and keep it in VB.NET (that goes without saying here), and as simple as possible.
 
Last edited:
THIS IS THE BEST I CAN DO FOR YOU, IT GIVES YOU AN EXAMPLE TO WORK WITH:
VB.NET:
# Determine Anchor and Active End of Selection

Dim textBox As New RichTextBox()
Dim anchor As Integer
Dim active As Integer

' Assuming the user has made a selection in the RichTextBox
anchor = textBox.SelectionStart
active = textBox.SelectionStart + textBox.SelectionLength

If anchor > active Then
    ' Swap values if anchor is greater than active
    Dim temp As Integer = anchor
    anchor = active
    active = temp
End If

' Now anchor and active represent the correct ends of the selection
 
Back
Top