Line length & count for multiline Text Box 
Author Message
 Line length & count for multiline Text Box

Does anyone know how do you count the number of lines and the length
of each line in a multiline Text Box?  I have the need to break up the
text in a multiline Text Box by lines and I hope I don't have to write
my own routine to do that.


Fri, 28 May 1999 03:00:00 GMT  
 Line length & count for multiline Text Box


> Does anyone know how do you count the number of lines and the length
> of each line in a multiline Text Box?  I have the need to break up the
> text in a multiline Text Box by lines and I hope I don't have to write
> my own routine to do that.

You certainly don't, Raymond! You can use the API SendMessage function for both these tasks.

To get the total number of lines in a multiline text box, use the following:

        TotalLines& = SendMessage(someTextBox.hWnd, EM_GETLINECOUNT, 0&, 0&)

To determine the length of a line, you need to get the index of the first character in the line
(put this in a loop to run through all the lines in the control as returned by EM_GETLINECOUNT):

        LineStart& = SendMessage(someTextBox.hWnd, EM_LINEINDEX, curLine, 0&)

Then use the returned value as an argument

        LineLen& = SendMessage(someTextBox.hWnd, EM_LINELENGTH, LineStart&, 0&)

The EM_GETLINECOUNT, EM_LINEINDEX and EM_LINELENGTH constants are &H400 + 10, &H400 + 11 and
&H400 + 17 respectively.

Good luck!

Mark Raishbrook

Sat, 29 May 1999 03:00:00 GMT  
 Line length & count for multiline Text Box

Hi Raymond,

> Does anyone know how do you count the number of lines and the length
> of each line in a multiline Text Box?  I have the need to break up the
> text in a multiline Text Box by lines and I hope I don't have to write
> my own routine to do that.

You can use the Windows API call "SendMessage" for that. I got the routines
for this out of Dan Appleman's book "The Visual Basic Programmer's Guide to
the Windows API".

-- Jim F, FMS

Sun, 30 May 1999 03:00:00 GMT  
 Line length & count for multiline Text Box

Went into

Search for: ("API") and ("text") and ("box") and ("manipulate")
Will give you more information.

Q141073 is at the end of this message.

Hope this helps

Abel Fontes
Using Windows API Functions to Better Manipulate Text Boxes

Article ID: Q141073
Creation Date: 11-DEC-1995
Revision Date: 07-MAY-1996

The information in this article applies to:
 Professional and Enterprise Editions of Microsoft Visual Basic, 16-bit
only, for Windows, version 4.0


By calling Windows API functions from Microsoft Visual Basic for Windows,
you can retrieve text box (or edit control) information that you cannot
obtain using only Visual Basic for Windows's built-in features.

NOTE: In Visual Basic versions 2.0, 3.0, and 4.0 for Windows, you can use
the new HWND property of a text box instead of calling the GetFocus()

This article supplies a sample program that performs the following useful
features (making use of the Windows message constants shown in
parentheses, obtained by calling Windows API routines):
 Copies a specific line of text from the text box (EM_GETLINE).  Retrieves
the number of lines within the text box (EM_GETLINECOUNT).  Positions the
cursor at a specific character location (EM_GETSEL) in the text box.
Retrieves the line number of a specific character location in the text box
(EM_LINEFROMCHAR).  Retrieves the amount of lines before a specified
character position in the text box (EM_LINEINDEX).  Retrieves the amount
of characters in a specified line in the text box (EM_LINELENGTH).
Replaces specified text with another text string (EM_REPLACESEL).

For a separate article that explains how to specify the amount of text
allowable within a text control, query on the following word in the
Microsoft Knowledge Base:



NOTE: As of 3/25/92, the code below corrects the VBKNOWLG.HLP file shipped
with the Microsoft Professional Toolkit for Visual Basic version 1.0 for

NOTE: Using the SelStart, SelLength, and SelText properties may be easier
than using EM_GETSEL and EM_REPLACESEL below.

The Windows API file USER.EXE defines the SendMessage function that
returns or performs a specific event on your edit control. To create an
example that displays specific information about your edit control, do the
1.Create a form (Form1), and add the following controls and properties:

Control Control Name Height Left Top Width
------------------------------------------------------------ Label
aGetLine 360 120 Label aGetLineCount 360 480 Label aGetSel 360 840 Label
aLineFromChar 360 1200 Label aLineIndex 360 1560 Label aLineLength 360
1920 Label aReplaceSel 360 2280 Command Command1 375 360 2640 1815 Text
Text1 1815 2640 480 3495 Text Text2 375 2520 2640 3615 2.Set each label's
AutoSize property to True. 3.Set the Text1.MultiLine property to True.
4.Change the Command1.Caption to "Insert this text --->". 5.Add the
following code to the global Declarations section of Form1:

Private Declare Function GetFocus% Lib "user" () ' Enter the following
Declare as one, single line: Private Declare Function SendMessage& Lib
"user"(ByVal hWnd%, ByVal

         ByVal wParam%, ByVal lParam As Any)
   ' lParam is actually a double word, or long, but declaring
   ' lParam "As Any" allows flexibility for certain cases of
   ' using SendMessage.

 After adding the code listed below to your form, run the program.
   Whenever a key is released, the labels will be updated with the new
   information about your text box.

   Private Sub Form_Load ()
      X% = fReplaceSel("")   '* Used to display the correct text.
   End Sub

   Private Sub Text1_KeyUp (KeyCode As Integer, Shift As Integer)
      '* Update the text control information whenever the key
      '* is pressed and released.
      CharPos& = fGetSel()
      LineNumber& = fLineFromChar(CharPos&)
      X% = fGetLine(LineNumber&)
      X% = fGetLineCount()
      X% = fLineIndex(LineNumber&)
      X% = fLineLength(CharPos&)
   End Sub

   Private Sub Command1_Click ()
      '* This routine will insert a line of text at the current location
      '* of the caret.

      D$ = Text2.text
      CharPos& = fGetSel()
      X% = fReplaceSel(D$)
      X% = fSetSel(CharPos&)

      '* Text has been inserted at the caret location.  No update the
      '* text controls information.
      Call Text1_KeyUp(0, 0)
   End Sub

   Private Function fGetLineCount& ()
      '* This function will return the number of lines in the edit
      Const EM_GETLINECOUNT = &H400 + 10

      ' In versions 2.00 and 3.00, you need to use a long integer to avoid
      ' a bad DLL calling convention error message. As an alternative,
      ' you can use the new HWND property instead of GetFocus():
      Pos& = SendMessage(GetFocus(), EM_GETLINECOUNT, 0&, 0&)
      ' Use the following Pos& if you have Visual Basic version 1.0:
      ' Pos& = SendMessage(GetFocus(), EM_GETLINECOUNT, 0%, 0%)
      aGetLineCount.Caption = "GetLineCount = " + Str$(Pos&)
      fGetLineCount = Pos&
   End Function

   Private Function fGetLine (LineNumber As Long)
      '* This function copies a line of text specified by LineNumber
      '* from the edit control. The first line starts at zero.

      Const MAX_CHAR_PER_LINE = 80
      Const EM_GETLINE = &H400 + 20

      byteLo% = MAX_CHAR_PER_LINE And (255)  '[changed 3/25/92]
      byteHi% = Int(MAX_CHAR_PER_LINE / 256) '[changed 3/25/92, two
      Buffer$ = chr$(byteLo%) + chr$(byteHi%) +

      Pos& = SendMessage(GetFocus(), EM_GETLINE, CINT(LineNumber),
      aGetLine.Caption = "GetLine = " + Buffer$
      fGetLine = Pos&

   End Function

   Private Function fGetSel& ()
      '* This function returns the starting/ending position of the
      '* current selected text.  This is the current location of the
      '* cursor if start is equal to ending.
      '* LOWORD-start position of selected text
      '* HIWORD-first no selected text

      Const EM_GETSEL = &H400 + 0

      location& = SendMessage(GetFocus(), EM_GETSEL, 0, 0&)
      ending% = location& \ &H10000
      starting% = location& And &H7FFF
      aGetSel.Caption = "Caret Location = " + Str$(starting%)
      fGetSel = location& mod 65536
   End Function

   Private Function fLineFromChar& (CharPos&)
      '* This function will return the line number of the line that
      '* contains the character whose location(index) specified in the
      '* third argument of SendMessage. If the third argument is -1,
      '* then the number of the line that contains the first character
      '* of the selected text is returned. If start = end from GetSel,
      '* then the current caret location is used. Line numbers start
      '* at zero.

      Const EM_LINEFROMCHAR = &H400 + 25

      Pos& = SendMessage(GetFocus(), EM_LINEFROMCHAR, CINT(CharPos&), 0&)
      aLineFromChar.Caption = "Current Line = " + Str$(Pos&)
      fLineFromChar = Pos&
   End Function

   Private Function fLineIndex (LineNumber As Long)
      '* This function will return the number of bytes that
      '* precede the given line. The returned number reflects the CR/LF
      '* after each line. The third argument to SendMessage specifies
      '* the line number, where the first line number is zero. If the
      '* third argument to SendMessage is -1, then the current line
      '* number is used.

      Const EM_LINEINDEX = &H400 + 11

      Pos& = SendMessage(GetFocus(), EM_LINEINDEX, CINT(LineNumber), 0&)
      aLineIndex.Caption = "#Char's before line = " + Str$(Pos&)
      fLineIndex = Pos&
   End Function

   Private Function fLineLength& (CharPos As Long)
      '* This function will return the length of a line in the edit
      '* control. CharPos specifies the index of the character that
      '* is part of the line that you would like to find the length. If
      '* this argument is -1, the current selected character is used as
      '* the index.

      Const EM_LINELENGTH = &H400 + 17
      Pos& = SendMessage(GetFocus(), EM_LINELENGTH, CINT(CharPos), 0&)
      aLineLength.Caption = "LineLength = " + Str$(Pos&)
      fLineLength = Pos&
   End Function

   Private Function fSetSel& (Pos&)
      '* This function selects all characters in the current text that
      '* are within the starting and ending positions given by
      '* Location. The low word is the starting position and the high
      '* word is the ending position. If you set start to end, this
      '* can be used to position the cursor within the edit control.

      Const EM_SETSEL = &H400 + 1
      location& = Pos& * 2 ^ 16 + Pos&
      X% = SendMessage(GetFocus(), EM_SETSEL, 0%, location&)
      fSetSel = Pos&
   End Function

   Private Function fReplaceSel (Buffer$)
      '* This function will replace the current selected text with the
      '* new text specified in Buffer$. You must call SendMessage with
      '* the EM_GETSEL constant to select text.

      Const EM_REPLACESEL = &H400 + 18
      Pos& = SendMessage(GetFocus(), EM_REPLACESEL, 0%, Buffer$)
      aReplaceSel.Caption = "String inserted = " + Buffer$
      fReplaceSel = Pos&
   End Function


"Programming Windows: The Microsoft Guide to Writing Applications for
Windows 3," Charles Petzold, Microsoft Press, 1990

"Microsoft Windows Software Development Kit: Reference Volume 1," version

WINSDK.HLP file shipped with Microsoft Windows 3.0 Software Development

The Professional and Enterprise Editions of Visual Basic 4.0 contain all
the necessary SDK references in the MSDN/VB Starter Kit.

Wed, 02 Jun 1999 03:00:00 GMT  
 [ 4 post ] 

 Relevant Pages 

1. Assigning Multi line text to a multiline text box

2. ? Text Box: multi line; fixed length per line

3. Limitting line length of each line within multiline textbox

4. HELP! Counting carriage returns in multiline text box

5. HELP Counting carriage returns in multiline text box

6. Counting lines of text in a text box ????

7. Starting new line on multiline text box

8. Reading a single line in a multiline text box

9. Using API or other method to count number of lines in a Rich Text Box

10. counting lines in a text box

11. Newbie: creating a fixed-line-length file from a variable-line-length file

12. Adding text to a multiline text box


Powered by phpBB® Forum Software