View Full Version : Listbox and Textbox - Adding information from file.
Hi
I am using ThinBasic version 1.13.0, and testing the listbox example (...\SampleScript\UI\Listbox\Listbox.tBbasic). Trying to populate the listbox from a text file but I cannot get the items to appear as a single line. That is the text file is:
one
two
three
Then the list box is: onetwothree; for many lines.
I tried using the C++ escape code '\n' with similar results. How do I get the program to read a single word to populate the listbox.
Also, if I am using a textbox how do I get the program to read several paragraphs into the Textbox. Thank You...
ErosOlmi
25-06-2024, 17:19
Ciao,
I think there is a problem in passing array of elements from file.
I'm checking why and will post here a new thinBasic_UI.dll to test
Regarding paragraph in standard textbox you need to add some textbox styles like %ES_MULTILINE and %ES_WANTRETURN
Eros
Eros - Thank You...
Ciao,
I think there is a problem in passing array of elements from file.
I'm checking why and will post here a new thinBasic_UI.dll to test
Regarding paragraph in standard textbox you need to add some textbox styles like %ES_MULTILINE and %ES_WANTRETURN
Eros
ErosOlmi
26-06-2024, 12:09
Attached a new thinBasic UI module.
Please copy thinBasic_UI.dll into \thinbasic\lib\ path and replace your current one.
What I've done was to recode the way thinBasic load string array data into a ListBox when using "Control Add Listbox ..." or "Listbox Add ..." or "Control Add Combobox ..." or "Combobox Add ..."
Not sure I've solved 100% what you was trying to do.
If not, please post a little example showing how to replicate the problem.
Ciao
Eros
Thank You, I will try it out this weekend and let you know if it worked. Take care...
Attached a new thinBasic UI module.
Please copy thinBasic_UI.dll into \thinbasic\lib\ path and replace your current one.
What I've done was to recode the way thinBasic load string array data into a ListBox when using "Control Add Listbox ..." or "Listbox Add ..." or "Control Add Combobox ..." or "Combobox Add ..."
Not sure I've solved 100% what you was trying to do.
If not, please post a little example showing how to replicate the problem.
Ciao
Eros
Thank You, I will try it out this weekend and let you know if it worked. Take care...
Hi - Very Very strange. I replaced the ThinBasic_UI.dll file and the TRACE does no work. I reinstalled Thinbasic without the updated DLL and Trace still does not work. Still having issues with the list box. The program with the new DLL continues to read the input as a single line (Please see attached). Below is the code I left the three vlist lines to show what I have tried. Any help would be appreciated. Thank You...
uses "UI"
uses "file"
USES "CONSOLE"
Uses "Trace"
DIM tmpStr AS STRING
dim tmpLong as long
dim ID_List01 as long
dim MaxItems as long
dim CurItem as long
dim count as long
dim MaxElements as long = 100
dim vList(MaxElements) AS STRING
' *******
dim InFileToLoad as string
dim InFileChannel as long
Dim i As Integer
Dim iTm (15) As Integer
dim sBuffer as string
InFileToLoad = app_sourcepath & "Out5.txt"
' ******
Begin ControlID
%Text01
%List01
%Butt01
End ControlID
function TBMain()
DIM hDlg AS LONG
'---Create a new dialog
DIALOG NEW 0, "ListBox example", -1, -1, 275, 120, _
%WS_DLGFRAME OR %DS_CENTER OR %WS_CAPTION OR %WS_SYSMENU, _
0 TO hDlg
randomize
'*******
InFileChannel = file_open(InFileToLoad , "INPUT" )
i = 1
while not file_eof(InFileChannel)
sBuffer = file_lineinput(InFileChannel)
print sBuffer
iTm(15) = sBuffer
i=i+1
wend
i = 1
FOR count = 1 TO MaxElements
' Works Fine - give Item and number
' vList(Count) = "Item " & FORMAT$(RND(1, 100000), "000000")
' Does not work - gives only "ten"
' vList(Count) = sBuffer ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
' Does not work - gives "Subscript out of range in array or matrix
'Dimension 1 should be between 1 and 15. Current value: 16"
vList(Count) = iTm (i) 'sBuffer ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
i = i+1
NEXT
' ******
'---Show dialog in MODAL state
DIALOG SHOW MODAL hDlg, call dlgCallback
end function
callback function dlgCallback() as long
'---Now test the message
SELECT CASE cbMsg
case %WM_INITDIALOG '---Message fired at the very beginning when dialog is initialized
'---This can be the right place to initialize dialog or create controls
CONTROL ADD listbox , cbHndl, %List01 , vList() , 5, 20, 200, 100, 0, 0
CONTROL ADD textbox , cbHndl, %Text01 , "" , 5, 5, 200, 12
control add button , cbHndl, %Butt01 , "Set" , 210, 5, 60, 12
CASE %WM_COMMAND
'---Test which control has been clicked
SELECT CASE cbCtl
'---Something has happened with %List01
case %List01
select case cbCtlMsg
case %LBN_SELCHANGE
LISTBOX GET TEXT cbHndl, %List01 TO tmpStr
control set text cbHndl, %Text01, tmpStr
case %LBN_DBLCLK
LISTBOX GET TEXT cbHndl, %List01 TO tmpStr
control append text cbHndl, %Text01, "(DblClick " & tmpStr & ")"
end select
case %Butt01
if cbCtlMsg = %BN_CLICKED then
'---Get the text from a textbox and place into a string
control get text cbHndl, %Text01 to tmpStr
'---Get the window unique ID of the control
CONTROL HANDLE cbHndl, %List01 TO ID_List01
'---Get the number of items present into listbox
MaxItems = sendmessage(ID_List01, %LB_GETCOUNT, 0, 0)
'---Get current selected item (remember it start at zero position)
listbox get selected cbHndl, %List01 to CurItem
'---Now delete selected item ...
listbox delete cbHndl, %List01, CurItem
'---...and insert new text in same position
sendmessage(ID_List01, %LB_INSERTSTRING, CurItem - 1, strptr(tmpStr))
listbox select cbHndl, %List01, CurItem
end if
end select
END SELECT
end function
10370
Petr Schreiber
30-06-2024, 11:35
Dear KF4GHG,
I would like to attempt to offer an insight into the problems you experience in your code.
Observation #1
dim MaxElements as long = 100 ' MaxElements is set to 100
dim vList(MaxElements) AS STRING ' vList has 100 elements
...
Dim iTm (15) As Integer ' iTm has however just 15 elements
Observation #2
InFileChannel = file_open(InFileToLoad , "INPUT" )
i = 1
while not file_eof(InFileChannel)
sBuffer = file_lineinput(InFileChannel)
print sBuffer
iTm(15) = sBuffer
i=i+1
wend
We can see in this part that sBuffer variable will contain only the last read value from the file after leaving while cycle
Problematic part:
i = 1
FOR count = 1 TO MaxElements
' Works Fine - give Item and number
' vList(Count) = "Item " & FORMAT$(RND(1, 100000), "000000")
' Does not work - gives only "ten"
' vList(Count) = sBuffer ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
' Does not work - gives "Subscript out of range in array or matrix
'Dimension 1 should be between 1 and 15. Current value: 16"
vList(Count) = iTm (i) 'sBuffer ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
i = i+1
NEXT
The issue on line 7 is not really an issue - it gives only single value because of the fact highlighted in the Observation #2
The issue on line 11 occurs for the following reason:
- the FOR cycle goes from 1 to MaxElements, that is 1 to 100
- the i variable will also grow from 1 to 100, thanks to the way you initialize it to 1 before the cycle and increase by one at the end of the cycle
- the iTm array is dimensioned just for 15 elements, as seen in Observation #1
I hope this helps getting you closer to your goal.
Petr
Hi Petr
Thank you for your suggestions. I made the suggested changes and modified the sBuffer to be a dimensional variable (sBuffer (i) = file_lineinput(InFileChannel)) but still am having issues. The vlist (vList(Count) = sBuffer(i))does not seem to work because it does not populate the listbox. sBuffer(i) does display on the consul but the multiline document comes out as a single line (i.e., onetwothreefourfivesixseveneightnineten...). Again thank You...
Dear KF4GHG,
I would like to attempt to offer an insight into the problems you experience in your code.
Observation #1
dim MaxElements as long = 100 ' MaxElements is set to 100
dim vList(MaxElements) AS STRING ' vList has 100 elements
...
Dim iTm (15) As Integer ' iTm has however just 15 elements
Observation #2
InFileChannel = file_open(InFileToLoad , "INPUT" )
i = 1
while not file_eof(InFileChannel)
sBuffer = file_lineinput(InFileChannel)
print sBuffer
iTm(15) = sBuffer
i=i+1
wend
We can see in this part that sBuffer variable will contain only the last read value from the file after leaving while cycle
Problematic part:
i = 1
FOR count = 1 TO MaxElements
' Works Fine - give Item and number
' vList(Count) = "Item " & FORMAT$(RND(1, 100000), "000000")
' Does not work - gives only "ten"
' vList(Count) = sBuffer ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
' Does not work - gives "Subscript out of range in array or matrix
'Dimension 1 should be between 1 and 15. Current value: 16"
vList(Count) = iTm (i) 'sBuffer ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
i = i+1
NEXT
The issue on line 7 is not really an issue - it gives only single value because of the fact highlighted in the Observation #2
The issue on line 11 occurs for the following reason:
- the FOR cycle goes from 1 to MaxElements, that is 1 to 100
- the i variable will also grow from 1 to 100, thanks to the way you initialize it to 1 before the cycle and increase by one at the end of the cycle
- the iTm array is dimensioned just for 15 elements, as seen in Observation #1
I hope this helps getting you closer to your goal.
Petr
Petr Schreiber
30-06-2024, 21:14
Thanks a lot for the comment.
If I understand correctly, the input file contains words on each line - right?
Then iTm array cannot be of type Integer to consume the data from the file, but of type String.
Once you do this change, the data will be added to the listbox. But there is a catch - a lot of empty items in listbox, and one, two, three... at the very end.
This is because you make the arrays huge by default, instead of modelling their size based on file content size.
ThinBasic can make this whole part:
InFileChannel = file_open(InFileToLoad , "INPUT" )
i = 1
while not file_eof(InFileChannel)
sBuffer = file_lineinput(InFileChannel)
printl sBuffer
iTm(i) = sBuffer
i=i+1
wend
...much simpler for you. Consider this two liner instead:
String iTm() ' Notice you don't have to specify size ahead!
PARSE(FILE InFileToLoad, iTm, $CRLF) ' Loads each line in file to appropriate iTm array item
...you can then anytime get the number of items in array by:
CountOf(iTm)
So if you want vList to have the same number of items, you can do:
DIM vList(CountOf(iTm)) AS STRING
Or if you want to iterate over all items in the array:
FOR i = 1 to CountOf(iTm)
NEXT
Hope it helps,
Petr
Hi
Fixed the identified problems, but still having issue with the FOR statement:
....
dim count as long = 15
dim MaxElements as long = 15
dim vList(15) AS STRING
dim i As Integer = 15
dim iTm (15) As String
dim sBuffer (15) as string
...
i = 0
FOR count = 1 TO 15
vList(Count) = iTm(Count)
i = i+1
NEXT
I get a "...Subscript out of range in array or matrix..." error. Even though the variables are set to 15. Thank You...
Yann_F_29
06-07-2024, 20:38
Hi
Fixed the identified problems, but still having issue with the FOR statement:
....
dim count as long = 15
dim MaxElements as long = 15
dim vList(15) AS STRING
dim i As Integer = 15
dim iTm (15) As String
dim sBuffer (15) as string
...
i = 0
FOR count = 1 TO 15
vList(Count) = iTm(Count)
i = i+1
NEXT
I get a "...Subscript out of range in array or matrix..." error. Even though the variables are set to 15. Thank You...
Hi,
Your exanple as displayed, works fine. The subscript error is not in this part of code.
Carefully check the line where the error is reported.
And also, remember that in ThinBasic, not as other old basics, the for counter is incremented when the last NEXT is reached.
If you check 'count' after the NEXT statement, it will contain 16.
Yann
Petr Schreiber
08-07-2024, 09:53
I agree with Yann's analysis.
Seeing that i variable initialization and increment - if you use i as a subscript, it will be 0 in the first iteration.
As thinBASIC arrays are 1 based, it could cause the problem.
Maybe it would help to share full code, ideally wrapped using CODE tags, so we can refer to specific line more easily (see # button on toolbar when editing your post to generate the tags for you).
Petr
Thank you below is the code. i get a 400 error on line 68. The Out5.txt file is:
one
two
three
...
Ten
-------------------------------------------------------------
uses "UI"
uses "file"
USES "CONSOLE"
dim tmpStr AS STRING
dim tmpLong as long
dim ID_List01 as long
dim MaxItems as long
dim CurItem as long
dim Count as Integer
dim MaxElements as long = 15 ' = 100
dim vList(15) AS STRING
' *******
dim InFileToLoad as string
dim InFileChannel as long
Dim i As Integer
Dim iTm (15) As String
dim sBuffer (15) as string
InFileToLoad = app_sourcepath & "Out5.txt"
' ******
Begin ControlID
%Text01
%List01
%Butt01
End ControlID
function TBMain()
DIM hDlg AS LONG
'---Create a new dialog
DIALOG NEW 0, "ListBox example", -1, -1, 275, 120, _
%WS_DLGFRAME OR %DS_CENTER OR %WS_CAPTION OR %WS_SYSMENU, _
0 TO hDlg
randomize
'*******
InFileChannel = file_open(InFileToLoad , "INPUT" )
i = 1
while not file_eof(InFileChannel)
iTm (i) = file_lineinput(InFileChannel)
print iTm(i)
i=i+1
wend
String iTm() ' Notice you don't have to specify size ahead!
PARSE(FILE InFileToLoad, iTm(), $CRLF)
i = 1
FOR count = 1 TO 15 ' MaxElements
vList(Count) = iTm(i) 'sBuffer(i) ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
i = i+1
NEXT
' ******
'---Show dialog in MODAL state
DIALOG SHOW MODAL hDlg, call dlgCallback
end function
callback function dlgCallback() as long
'---Now test the message
SELECT CASE cbMsg
case %WM_INITDIALOG '---Message fired at the very beginning when dialog is initialized
'---This can be the right place to initialize dialog or create controls
CONTROL ADD listbox , cbHndl, %List01 , vList() , 5, 20, 200, 100, 0, 0
CONTROL ADD textbox , cbHndl, %Text01 , "" , 5, 5, 200, 12
control add button , cbHndl, %Butt01 , "Set" , 210, 5, 60, 12
CASE %WM_COMMAND
'---Test which control has been clicked
SELECT CASE cbCtl
'---Something has happened with %List01
case %List01
select case cbCtlMsg
case %LBN_SELCHANGE
LISTBOX GET TEXT cbHndl, %List01 TO tmpStr
control set text cbHndl, %Text01, tmpStr
case %LBN_DBLCLK
LISTBOX GET TEXT cbHndl, %List01 TO tmpStr
control append text cbHndl, %Text01, "(DblClick " & tmpStr & ")"
end select
case %Butt01
if cbCtlMsg = %BN_CLICKED then
'---Get the text from a textbox and place into a string
control get text cbHndl, %Text01 to tmpStr
'---Get the window unique ID of the control
CONTROL HANDLE cbHndl, %List01 TO ID_List01
'---Get the number of items present into listbox
MaxItems = sendmessage(ID_List01, %LB_GETCOUNT, 0, 0)
'---Get current selected item (remember it start at zero position)
listbox get selected cbHndl, %List01 to CurItem
'---Now delete selected item ...
listbox delete cbHndl, %List01, CurItem
'---...and insert new text in same position
sendmessage(ID_List01, %LB_INSERTSTRING, CurItem - 1, strptr(tmpStr))
listbox select cbHndl, %List01, CurItem
end if
end select
END SELECT
end function
I agree with Yann's analysis.
Seeing that i variable initialization and increment - if you use i as a subscript, it will be 0 in the first iteration.
As thinBASIC arrays are 1 based, it could cause the problem.
Maybe it would help to share full code, ideally wrapped using CODE tags, so we can refer to specific line more easily (see # button on toolbar when editing your post to generate the tags for you).
Petr
Yann_F_29
11-07-2024, 00:32
Thank you below is the code. i get a 400 error on line 68. The Out5.txt file is:
Hi KF4GHG
The debugging of your code was not obvious
Look at the line flagged by " 'add Yann ============================"
An instruction you should know and use "
Ubound(Array)" it shows the upper boud of an Array , often the size of the array
uses "UI"
uses "file"
USES "CONSOLE"
%red_text = 12 'add Yann ============================================
dim tmpStr AS STRING
dim tmpLong as long
dim ID_List01 as long
dim MaxItems as long
dim CurItem as long
dim Count as Integer
dim MaxElements as long = 15 ' = 100
dim vList(15) AS STRING
' *******
dim InFileToLoad as string
dim InFileChannel as long
Dim i As Integer
Dim iTm (15) As String
dim sBuffer (15) as string
InFileToLoad = app_sourcepath & "Out5.txt"
' ******
Begin ControlID
%Text01
%List01
%Butt01
End ControlID
function TBMain()
DIM hDlg AS LONG
'---Create a new dialog
DIALOG NEW 0, "ListBox example", -1, -1, 275, 120, _
%WS_DLGFRAME OR %DS_CENTER OR %WS_CAPTION OR %WS_SYSMENU, _
0 TO hDlg
randomize
'*******
printl ubound(itm) in %red_text 'add Yann ================================================ should be 15 as defined in line 22
InFileChannel = file_open(InFileToLoad , "INPUT" )
i = 1
while not file_eof(InFileChannel)
iTm (i) = file_lineinput(InFileChannel)
print iTm(i)
i=i+1
wend
String iTm() ' Notice you don't have to specify size ahead!
printl ubound(itm) in %red_text 'add Yann =================================== ahah now = 0 the preceding line sets size of iTm array to zero
'add Yann =================================== in fact it redefines iTm array without a real size so this line should be suppressed
'add Yann ==================================================
printl PARSE(FILE InFileToLoad, iTm(), $CRLF) in %red_text
'add Yann =======================================curiously the count is one and the array is empty
'add Yann ======================================= the reason is not obvious
'add Yann ======================================= I then tryed to load the file in a buffer and print len and content of the buffer
'add Yann ======================================= The len was 0 zero and effectively nothing in the buffer
'add Yann ======================================= Then I reread the code .... line 47 File_Open (InFileToLoad , "INPUT" ) ...OK
'add Yann ======================================= But nowhere File_Close
'add Yann ======================================= The parsefile uses the opend file who reached EOF and load nothing
'add Yann =======================================
'add Yann ======================================= So add : file_close(infilechannel) after Wend and Parse will do better
i = 1
FOR count = 1 TO 15 ' MaxElements
vList(Count) = iTm(i) 'sBuffer(i) ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
i = i+1
NEXT
' ******
.
.
.
.
.
.
end function
I simplified the code lines 50 -- 54 by loading the file data in a buffer and parsing that buffer.
The code fails now : because PARSE redimension iTm array to the number of elements parsed
The loop in lines 63 to 66 have to be modified to agree with the element count which could be obtained
For example by using for count = 1 to maxelements
and maxelements = PARSE(data_buffer, iTm(), $CRLF)
and as you open a Console, I suggest you to use many Printl lines, to follow the way your script follows
Enjoy.:yahoo:
Yann
element_count = PARSE(data_buffer.......
'---Script created on 2024-07-10 21:00:49.595 by
uses "UI"
uses "file"
USES "CONSOLE"
%red_text = 12
dim parse_count_file as long
dim data_buffer as string
dim tmpStr AS STRING
dim tmpLong as long
dim ID_List01 as long
dim MaxItems as long
dim CurItem as long
dim Count as Integer
dim MaxElements as long = 15 ' = 100
dim vList(15) AS STRING
' *******
dim InFileToLoad as string
dim InFileChannel as long
Dim i As Integer
Dim iTm (15) As String
dim sBuffer (15) as string
itm(12) = "xxxx"
InFileToLoad = app_sourcepath & "Out5.txt"
' ******
Begin ControlID
%Text01
%List01
%Butt01
End ControlID
function TBMain()
DIM hDlg AS LONG
'---Create a new dialog
DIALOG NEW 0, "ListBox example", -1, -1, 275, 120, _
%WS_DLGFRAME OR %DS_CENTER OR %WS_CAPTION OR %WS_SYSMENU, _
0 TO hDlg
randomize
'*******
data_buffer = file_load(InFileToLoad)
maxelements = PARSE(data_buffer, iTm(), $CRLF) ' see note
i = 1
FOR count = 1 TO MaxElements 'see note
vList(Count) = iTm(i) 'sBuffer(i) ' "Ronnie Item " & FORMAT$(RND(1, 100000), "000000")
i = i+1
NEXT
' ******
'---.
.
.
.
.
..
Hi Yann -
Thank you it worked. One strange thing is that the list box, which gets the information from a text file does not post the information in the order it was received. That is the text file is one, two,... ten and the list box first shows several blank lines and then eight, five, four, nine, one, seven... Again, thank you...
Petr Schreiber
21-07-2024, 10:28
Dear KF4GHG,
you may consider having a closer look at Style and ExStyle parameters for Control Add Listbox and submitting them explicitly instead of passing zeroes.
I suspect it could help. I don't remember if 0 is handled as "default", but help mentions the default Style is %LBS_NOTIFY Or %LBS_SORT Or %WS_TABSTOP Or %WS_VSCROLL, which means it sorts everything, which is not what you may want.
Petr
Petr - Thank you for your suggestion. I will check it out... Ronnie
Dear KF4GHG,
you may consider having a closer look at Style and ExStyle parameters for Control Add Listbox and submitting them explicitly instead of passing zeroes.
I suspect it could help. I don't remember if 0 is handled as "default", but help mentions the default Style is %LBS_NOTIFY Or %LBS_SORT Or %WS_TABSTOP Or %WS_VSCROLL, which means it sorts everything, which is not what you may want.
Petr