March 6, 2021
Hot Topics:

Extending the TextBox Control

  • By Joacim Andersson
  • Send Email »
  • More Articles »

Now, let's go to work, first you have to declare the SendMessage API function:

Public Declare Function SendMessage _
Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long

You also need to declare the messages you want to send to the textbox. Let's say you want to write a wrapper function that can tell you the index of the first visible line in the textbox. Then you have to declare the following message:


Now you can go ahead and write the function:

Public Function TopLineIndex(txtBox As TextBox) As Long
TopLineIndex = SendMessage(txtBox.hWnd, _
End Function

The EM_GETFIRSTVISIBLELINE message doesn't take any arguments so wParam and lParam must be set to 0 (zero). If you want to use this function on a rich text box instead of the standard textbox then just change the argument type to RichTextBox instead of TextBox in the TopLineIndex function. Remember that the line index is zeroing based i.e. the function returns 0 for the first line, 1 for the second and so on.

A rich text box has a method called GetLineFromChar which returns the line index of the given character indexes. The standard textbox lack such a method though. Let's fix that! You need to use the EM_LINEFROMCHAR message witch is declared in the following manner:


The EM_LINEFROMCHAR message takes the index of the character position in the wParam argument.

Public Function GetLineFromChar(txtBox As TextBox, CharPos As Long) As Long
GetLineFromChar = SendMessage( _
txtBox.hWnd, EM_LINEFROMCHAR, CharPos, 0&)
End Function

So if you want to know what line the text caret is on in a multiline textbox you could call the function in this manner:

Dim lngLineIndex As Long
lngLineIndex = GetLineFromChar(Text1, Text1.SelStart)
MsgBox "You are on line number " & lngLineIndex + 1

Again remember that the line index is zero based.

You can also do the opposite, finding the index of the first character of a line, with the EM_LINEINDEX message.

Public Const EM_LINEINDEX = &HBB

Public Function GetCharFromLine(txtBox As TextBox, LineIndex As Long) As Long
GetCharFromLine = SendMessage( _
txtBox.hWnd, EM_LINEINDEX, LineIndex, 0&)
End Function

Now that we know how to find out what line we currently standing on wouldn't it be nice to find out how many lined of text there is in the textbox? Well that's easily done if you know of the EM_GETLINECOUNT message. This message doesn't take any arguments so we must pass 0 to wParam and lParam.


Public Function LineCount(txtBox As TextBox) As Long
LineCount = SendMessage( _
TxtBox.hWnd, EM_GETLINECOUNT, 0&, 0&)
End Function

OK that was simple enough. Let us go on to the next message: EM_LINELENGTH. This message takes a character index in the wParam argument and returns the length of the line which contains that character:

Public Const EM_LINELENGTH = &HC1

Public Function LineLen(txtBox As TextBox, CharPos As Long) As Long
LineLen = SendMessage( _
TxtBox.hWnd, EM_LINELEENGTH, CharPos, 0&)
End Function

Page 2 of 3

This article was originally published on November 20, 2002

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date