Older Version Newer Version

JanetTerra JanetTerra Feb 9, 2007

Retrieving Information from Textboxes


The Native Liberty BASIC Command


Liberty BASIC has a native command for retrieving textbox contents -
 Print #main.tbx1, "!Contents? text$" 
In most instances, this is all the code programs require.
 WindowWidth = 400 
WindowHeight = 300
UpperLeftX = Int((DisplayWidth - WindowWidth) /2)
UpperLeftY = Int((DisplayHeight - WindowHeight) /2)
Statictext #main.stx1, "What is your name?", 20, 34, 70, 60
Textbox #main.tbx1, 100, 50, 200, 30
Button #main.default, " OK ", GetName, UL, 320, 50
Open "Retrieving Textbox Contents" for Dialog as #main
#main, "Trapclose XbyTrap"
#main, "Font Times_New_Roman 12 Bold"


Wait

Sub XbyTrap handle$
Close #handle$
End
End Sub

Sub GetName handle$
#main.tbx1, "!Contents? name$"
Notice "Hello, ";name$
End Sub

A Multiline Textbox


There are times when a multiline, word wrapping textbox may be preferred over the native Liberty BASIC texteditor. See also An Improved Stylebits Textbox.

There may also be a need to
  1. Get the number of lines in the textbox
  2. Get the number of characters in each line of text
  3. Get each separate line of text

These functions are possible with an API call to #user32, "SendMessageA" .

CallDLL #user32, "SendMessageA"


The SendMessageA function sends a specified messsage to a window or a control. The arguments to be passed include
When the message is received, the return value specifies the result of the message processing.

Visit the MSDN Library for more information about SendMessage.

Get the Number of Lines in the Textbox


The Windows constant _EM_GETLINECOUNT is the message used to retrieve the number of lines from a textbox.
 CallDLL #user32, "SendMessageA", _ 
hText as Ulong, _ ' handle of the textbox
_EM_GETLINECOUNT as Long, _ ' message to be passed
0 as Long, _ ' no further information to be passed
0 as Long, _ ' no further information to be passed
result as Long ' Windows returns the number of lines
Here is a demo to get the number of lines in a textbox. The mainwindow is kept visible for the printing of returned information. You may need to reposition your GUI window to see this information.
 ' Define a textbox 
Textbox #main.tb, 10, 20, 150, 68

' Stylebits for word wrapping and vertical scrolling
Stylebits #main.tb, _WS_VSCROLL OR _ES_MULTILINE, _ES_AUTOHSCROLL, 0, 0

' Define text
demoText$ = "All Gaul is divided into three parts, one of " + _
"which the Belgae inhabit, the Aquitani another, those who " + _
"in their own language are called Celts, in our Gauls, the third. " + _
"All these differ from each other in language, customs, and laws."

Open "Lines of Multiline Textbox" for Window as #main
#main, "Trapclose XbyTrap"
#main, "Font Times_New_Roman 10 bold"

' Print the text in the textbox
#main.tb, demoText$

' Get the handle of the textbox
hText=hWnd(#main.tb)

' Pass the required arguments to SendMessageA API
nLines = ReturnedMessage(hText, _EM_GETLINECOUNT, 0, 0)
Print "There are ";nLines;" lines in this textbox."

Wait

' Program ends here
Sub XbyTrap handle$
Close #handle$
End
End Sub

' SendMessageA Function
Function ReturnedMessage(handle, Msg, wParam, lParam)
CallDLL #user32, "SendMessageA", _
handle as Ulong, _
Msg as Long, _
wParam as Long, _
lParam as Long, _
ReturnedMessage as Long
End Function

Get the Number of Characters in Each Line of Text


SendMessageA will not return the actual text string. Instead, it returns the number of characters in that string. This next demo is the same as the previous demo, with a function added to get the number of characters at the end of each line. It is important to recognize that the function does not return the number of characters in that line, but the number of characters from the beginning of the text to the end of that line . Again using the API call SendMessageA , the handle of the textbox is passed as well as the message _EM_LINEINDEX . SendMessageA also needs to know which line is being questioned. The first available extra information argument, wParam , passes the line number to be queried. There is no additional information needed, so the second informational argument, lParam , remains 0.
 CallDLL #user32, "SendMessageA", _ 
hText as Ulong, _ ' handle of the textbox
_EM_LINEINDEX as Long, _ ' message to be passed
lineNumber as Long, _ ' the queried line number
0 as Long, _ ' no further information to be passed
result as Long ' Windows returns the number of lines
Since the last line is treated a little differently, the loop must terminate at the next to the last line For i = 1 to nLines - 1 . The code for the last line immediately follows the loop.
 ' Define a textbox 
Textbox #main.tb, 10, 20, 150, 68

' Stylebits for word wrapping and vertical scrolling
Stylebits #main.tb, _WS_VSCROLL OR _ES_MULTILINE, _ES_AUTOHSCROLL, 0, 0

' Define text
demoText$ = "All Gaul is divided into three parts, one of " + _
"which the Belgae inhabit, the Aquitani another, those who " + _
"in their own language are called Celts, in our Gauls, the third. " + _
"All these differ from each other in language, customs, and laws."

Open "Lines of Multiline Textbox" for Window as #main
#main, "Trapclose XbyTrap"
#main, "Font Times_New_Roman 10 bold"

' Print the text in the textbox
#main.tb, demoText$

' Get the handle of the textbox
hText=hWnd(#main.tb)

' Pass the required arguments to SendMessageA API
nLines = ReturnedMessage(hText, _EM_GETLINECOUNT, 0, 0)
Print "There are ";nLines;" lines in this textbox."

' Get the total number of characters at the end of each line
For i = 1 to nLines - 1
nCharacters = ReturnedMessage(hText, _EM_LINEINDEX, i, 0)
Print "Line #";i;": ";nCharacters;" Characters"
Next i

Wait

' Program ends here
Sub XbyTrap handle$
Close #handle$
End
End Sub

' SendMessageA Function
Function ReturnedMessage(handle, Msg, wParam, lParam)
CallDLL #user32, "SendMessageA", _
handle as Ulong, _
Msg as Long, _
wParam as Long, _
lParam as Long, _
ReturnedMessage as Long
End Function
How will knowing what the total number of characters reveal the actual number of characters in each line? By keeping track of how many characters were used in preceding lines, the number of characters already assigned is known. Subtract that number from the number of characters up to and including the selected line. The difference is the number of characters in just the selected line. Start the position, startPos , as 1.
 ' Define a textbox 
Textbox #main.tb, 10, 20, 150, 68

' Stylebits for word wrapping and vertical scrolling
Stylebits #main.tb, _WS_VSCROLL OR _ES_MULTILINE, _ES_AUTOHSCROLL, 0, 0

' Define text
demoText$ = "All Gaul is divided into three parts, one of " + _
"which the Belgae inhabit, the Aquitani another, those who " + _
"in their own language are called Celts, in our Gauls, the third. " + _
"All these differ from each other in language, customs, and laws."

Open "Lines of Multiline Textbox" for Window as #main
#main, "Trapclose XbyTrap"
#main, "Font Times_New_Roman 10 bold"

' Print the text in the textbox
#main.tb, demoText$
textLength = Len(demoText$)

' Get the handle of the textbox
hText=hWnd(#main.tb)

' Pass the required arguments to SendMessageA API
nLines = ReturnedMessage(hText, _EM_GETLINECOUNT, 0, 0)
Print "There are ";nLines;" lines in this textbox"

' The starting position is 1
startPos = 1

For i = 1 to nLines - 1
' Get the total number of characters in each line
nCharacters = ReturnedMessage(hText, _EM_LINEINDEX, i, 0)
' The characters in that line start with startPos and continue through to nCharacters
Print "Line ";i;": Characters ";startPos;" - ";nCharacters
' startPos moves up to the nCharacters pos for the next line
startPos = nCharacters + 1
Next i
' Get the number of characters in the last line by subtracting the nCharacters
' found thus far from the Length of the entire text
nCharacters = textLength - nCharacters
Print "Line ";i;": Characters ";startPos;" - ";textLength

'Wait for button to be pushed
Wait

' Program ends here
Sub XbyTrap handle$
Close #handle$
End
End Sub

' SendMessageA Function
Function ReturnedMessage(handle, Msg, wParam, lParam)
CallDLL #user32, "SendMessageA", _
handle as Ulong, _
Msg as Long, _
wParam as Long, _
lParam as Long, _
ReturnedMessage as Long
End Function

Liberty BASIC's Mid$() Function


Now that the starting and ending character position number is known, the Liberty BASIC Mid$() function can be used to extract that one line. The Mid$() function has 3 elements
  1. The whole text to be parsed (demoText$)
  2. The starting position (startPos)
  3. The number of characters to be extracted from the starting position to the right (nCharacters - startPos)

A simple demo of the Liberty BASIC Mid$() function -
 txt$ = "trouble" 
m$ = Mid$(txt$, 4, 3)
Print m$
End
Executing this code prints ubl , where u is the character in the fourth position of the string trouble , and ubl are the three characters in sequence beginning in this fourth position.

In this textbox demo, startPos becomes the start position and nCharacters - startPos becomes the sequence range of characters. Here is the code again, this time extracting and printing each line of text.
 ' Define a textbox 
Textbox #main.tb, 10, 20, 150, 68

' Stylebits for word wrapping and vertical scrolling
Stylebits #main.tb, _WS_VSCROLL OR _ES_MULTILINE, _ES_AUTOHSCROLL, 0, 0

' Define text
demoText$ = "All Gaul is divided into three parts, one of " + _
"which the Belgae inhabit, the Aquitani another, those who " + _
"in their own language are called Celts, in our Gauls, the third. " + _
"All these differ from each other in language, customs, and laws."

Open "Lines of Multiline Textbox" for Window as #main
#main, "Trapclose XbyTrap"
#main, "Font Times_New_Roman 10 bold"

' Print the text in the textbox
#main.tb, demoText$
textLength = Len(demoText$)

' Get the handle of the textbox
hText=hWnd(#main.tb)

' Pass the required arguments to SendMessageA API
nLines = ReturnedMessage(hText, _EM_GETLINECOUNT, 0, 0)
Print "There are ";nLines;" lines in this textbox"

' The starting position is 1
startPos = 1

For i = 1 to nLines - 1
' Get the total number of characters in each line
nCharacters = ReturnedMessage(hText, _EM_LINEINDEX, i, 0)
' Print that line of text using the Mid$() function
Print Mid$(demoText$, startPos, nCharacters - startPos)
' startPos moves up to the nCharacters pos for the next line
startPos = nCharacters + 1
Next i
' Get the number of characters in the last line by subtracting the nCharacters
' found thus far from the Length of the entire text
nCharacters = textLength - nCharacters
Print Mid$(demoText$, startPos, nCharacters)

'Wait for button to be pushed
Wait

' Program ends here
Sub XbyTrap handle$
Close #handle$
End
End Sub

' SendMessageA Function
Function ReturnedMessage(handle, Msg, wParam, lParam)
CallDLL #user32, "SendMessageA", _
handle as Ulong, _
Msg as Long, _
wParam as Long, _
lParam as Long, _
ReturnedMessage as Long
End Function
You may never need to extract single lines of text in a multiline textbox, but at least you know you can.