Click here to Skip to main content
Click here to Skip to main content

Tagged as

.NET Get Correct Caret Position from TextBox Control

, 8 Jul 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
How to get correct caret position from Textbox control

Introduction

If you do an Internet search for something like '.NET textbox caret position', most of the suggestions you will get are to use GetPositionFromCharIndex and pass in the SelectionStart value. This works as long as the caret is not at the end. If the caret is at the end, it always returns Point.Empty (0,0).

Background

I ran across this problem when trying to figure out how to position a help message next to a textbox.

If you use a reflector on the .NET framework, and view the code at System.Windows.Forms.TextBoxBase.GetPositionFromCharIndex(), you will see at the beginning of the function:

if (index < 0 || index >= this.Text.Length)
{
   return Point.Empty;
}

So with your TextBox control, you call TextBox1.GetPositionFromCharIndex(TextBox1.SelectionStart) you will get Point.Empty anytime SelectionStart is at the end (Internet Explorer, the user adding text and the caret is at the end of the content).

If the caret position is not at the beginning or end, then the .NET TextBoxBase will send a Windows message with an ID 214 to retrieve the position.

While still in a reflector, if you go over to System.Windows.Forms.RichTextBox.GetPositionFromCharIndex(), you will see something like:

if (index < 0 || index > this.Text.Length)
{
   return Point.Empty;
}

Note that this differs only by index >= this.Text.Length versus index > this.Text.Length. The code also sends out a Windows message with an ID 214 to retrieve the position.

Using the Code

You can do it the same way in the reflector, by sending your own Windows message, or you can use the GetCaretPos function in the User32.dll to get the position back. This method is considerably simpler in my opinion.

For instance, in C#, it would be:

[DllImport("user32.dll")]
private static extern bool GetCaretPos(out Point lpPoint);

public Point GetCorrectCaretPos()
{
    Point pt = Point.Empty;
    if (GetCaretPos(out pt))
    {
        return pt;
    }
    else
    {
        return Point.Empty;
    }
}

For VB.NET, it would be:

<DllImport("user32.dll")> _
Private Shared Function GetCaretPos(ByRef lpPoint As Point) As Boolean
End Function

Public Function GetCorrectCaretPos() As Point
    Dim pt As Point = Point.Empty
    If GetCaretPos(pt) Then
        Return pt
    Else
        Return Point.Empty
    End If
End Function

Points of Interest

I found it interesting that Microsoft fixed it for the RichTextBox control but not the TextBox control.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

B.O.B.
Software Developer (Senior)
United States United States
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 8 Jul 2014
Article Copyright 2014 by B.O.B.
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid