Author |
Topic: Numeric entry into a textbox (Read 2331 times) |
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #11 on: May 19th, 2016, 4:07pm » |
|
Thank you Richard for the corrected code. I'm afraid the blank look on my face is a bit more frequent these days. I could see what the problem was, the blank bit was nothing happening between the ears to solve it.
I thought I should have maphandle in there, but I didn't need it when I was using just a single dimension array. so I thought I was missing something, which clearly I was.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #12 on: May 19th, 2016, 5:18pm » |
|
on May 19th, 2016, 4:07pm, RNBW wrote:| I thought I should have maphandle in there, but I didn't need it when I was using just a single dimension array. |
|
In your 1D version you created the textboxes individually, rather than in a loop (with only three that wasn't too onerous) so you didn't need MAPHANDLE. But with a 2D grid of boxes it's much easier to create them using a nested loop, and increasingly so when the number of rows or columns increases.
As has been discussed here before, as soon as the number of rows and columns exceeds 10 you have to be a bit more careful about constructing the handles. The simple
Code:TB$(i,j) = "#main.tb" + str$(i) + str$(j) won't cut it in that case because (for example) i = 11, j = 1 would give exactly the same handle as i = 1, j = 11!
Richard.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #13 on: May 19th, 2016, 8:20pm » |
|
on May 19th, 2016, 5:18pm, Richard Russell wrote:| But with a 2D grid of boxes it's much easier to create them using a nested loop, and increasingly so when the number of rows or columns increases. |
|
This is of course an advantage that LBB has over LB, but it seems that nobody dares mention that at the LB Community Forum, where there is currently a parallel thread (despite it having been stated in the past that such a reference to LBB is allowed).
Richard.
|
|
Logged
|
|
|
|
Rod
Full Member
member is offline


Gender: 
Posts: 110
|
 |
Re: Numeric entry into a textbox
« Reply #14 on: May 20th, 2016, 08:00am » |
|
Just in case it isn't obvious leading zeroes is one solution.
Code:dim TB$(11,11)
j=1
i=11
TB$(i,j) = "#main.tb" + str$(i) + str$(j)
print TB$(i,j)
TB$(i,j) = "#main.tb" + right$("00"+str$(i),2) + right$("00"+str$(j),2)
print TB$(i,j)
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #15 on: May 20th, 2016, 08:34am » |
|
on May 20th, 2016, 08:00am, Rod wrote:| Just in case it isn't obvious leading zeroes is one solution. |
|
Indeed, or a simple separator character might be even easier:
Code: TB$(i,j) = "#main.tb"; i; "x"; j Richard.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #16 on: May 22nd, 2016, 3:28pm » |
|
on May 20th, 2016, 08:34am, Richard Russell wrote:Indeed, or a simple separator character might be even easier:
Code: TB$(i,j) = "#main.tb"; i; "x"; j Richard. |
|
Interesting. I didn't know that you could do that. You could write:
Code:
TB$(i,j) = "#main.tb"; "r"; i; "c"; j
to make it clear the row and column definition.
|
| « Last Edit: May 22nd, 2016, 3:29pm by RNBW » |
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #17 on: May 22nd, 2016, 4:23pm » |
|
User cundo at the LB Community Forum has posted a solution for a grid of textboxes, involving initially creating each one as a separate window (which is the only way you can do it in a loop in LB). Although messy - and slow - compared with the LBB method, it's a workable approach if LB compatibility is essential.
As documented in the Compatibility section of the LBB Help file (subsection 4), a small modification to his code is necessary to make it work in LBB. I've listed the revised program below (it still works in LB 4.5.0):
Code: NoMainWin
WindowWidth = 640
WindowHeight = 480
UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)
stylebits #main, 0, _WS_VISIBLE, 0, 0
Open "Window" for Window_nf as #main
#main "trapclose [quit]"
for y = 1 to 15 ' create the controls
for x= 1 to 6
ctrl=ctrl+1 ' number of controls
textbox #temp.t1,(100*x)-99, (25*y)-24,100,25
stylebits #temp, 0, _WS_VISIBLE, 0, 0
Open "" for Window_popup as #temp
maphandle #temp.t1, "#";ctrl;".t1" ' required for LBB
maphandle #temp, "#";ctrl
next x
next y
for i = 1 to ctrl 'attach the controls to the main handler and show them
h$= "#";i;".t1"
call setParent hWnd(#main) , hWnd(#h$)
call ShowWindow hWnd(#h$), 1
next i
call ShowWindow hWnd(#main), 1
[chkInput]
Timer 0
for u = 1 to ctrl
controlName$="#";u;".t1"
#controlName$ "!contents? txt$"
new$= remchar$(txt$,"abcdefghijklmn�opqrstuvwxyz")
if new$<>txt$ Then
#controlName$ new$
handle = Hwnd(#controlName$)
pos = Len(txt$)
CallDLL #user32, "SendMessageA",_
handle As long, _
_EM_SETSEL As long,_
pos As long,_
pos As long,_
result As void
End if
next
Timer 72, [chkInput]
wait
[quit]
close #main
for i = 1 to ctrl
closeMePlease$ = "#";i
close #closeMePlease$
next
end
sub setParent parent,child
calldll #user32, "SetParent",_
child as ulong,_
parent as ulong,_
r as void
End sub
Sub ShowWindow hWnd, flag
'SW_HIDE = 0
'SW_NORMAL = 1
CallDLL #user32, "ShowWindow",hWnd as uLong, flag As Long, r As void
End Sub
'include lb45func.bas Richard.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #18 on: May 23rd, 2016, 10:00am » |
|
To get the stylebits working properly in LBB should the stylebits for the textbox be:
Code:
stylebits #temp.t1, 0, _WS_BORDER, 0, 0
This enables you to get rid of the double border with the textboxes
Code:
textbox #temp.t1,(100*x)-100+50, (25*y)-25+50,100+1,25+1
Whilst the code does enable a grid to be set up in LB, using it with LBB is a bit slow setting up. Also, the fact that a list of 90 textbox controls is set up (1-90) it is not going to be as easy to access the controls as using the grid I have previously set up with RR help where the controls are accessed via row,col.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #19 on: May 23rd, 2016, 11:36am » |
|
on May 23rd, 2016, 10:00am, RNBW wrote:| Whilst the code does enable a grid to be set up in LB, using it with LBB is a bit slow setting up. |
|
It's quite slow in both LB and LBB, because it involves creating such a lot of windows. Maybe it's a little slower in LBB, because window creation is not normally on the critical path so has not been optimised. But either way if the time taken to create all those windows is an issue you could in many circumstances display a screen with instructions, or a dialog box requesting some input from the user, or just a logo, in order for that time not to be so noticeable.
After all it's only something you ever have to do once, sometime during program initialisation. You don't need to wait until the 'grid' is required before creating it, when the delay might indeed be more irritating. I often see programs that close and then reopen windows, when they could much more quickly hide and then re-show them.
Quote:| Also, the fact that a list of 90 textbox controls is set up (1-90) it is not going to be as easy to access the controls as using the grid I have previously set up with RR help where the controls are accessed via row,col. |
|
That's completely unrelated to the method used. Whether you create the boxes using LBB's nicer method or using cundo's method to achieve LB compatibility, it's entirely up to you whether you name the handles by a single value 1-90 or by row and column.
Strangely I find myself having to defend LB against unfair criticism in this case!
Richard.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #20 on: May 23rd, 2016, 1:31pm » |
|
I was not critising the code. I was making observations. I think the code is quite clever and gets over the problem of setting up a grid of textboxes in LB. However, I would suggest that accessing the textboxes via a row/col method is easier (and I think clearer) than trying to deal with a 90 item list of controls. It does mean that you'll have to set up the handles to deal with it.
In respect of speed; in this instance I found that the grid was displayed almost instantly in LB, whereas in LBB it could be seen building up a line of textboxes at a time before finally displaying the whole grid. As you say this can be overcome by creating the grid in the background, before displaying it.
Personally, I wouldn't use this method in LBB, because the grid solution that you came up with for me some time ago it's a much easier system to use.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #21 on: May 23rd, 2016, 4:00pm » |
|
on May 23rd, 2016, 1:31pm, RNBW wrote:| However, I would suggest that accessing the textboxes via a row/col method is easier |
|
I think you missed my point. The choice of how to name the textbox handles, either as a single number 1-90 or as row/col, is completely unrelated to the technique used to create those boxes. User cundo chose to use the single-number method, and in so doing has caused you to consider it one of the disadvantages of his approach, but it isn't. He could equally well have used the row/col method, and with hindsight it would have been better, because it would have avoided your misunderstanding.
Quote:| I found that the grid was displayed almost instantly in LB, whereas in LBB it could be seen building up a line of textboxes at a time before finally displaying the whole grid. |
|
I don't understand that. The code posted by cundo, and the slightly modified LBB-compatible code I posted, both created the window with the WS_VISIBLE style bit cleared and only 'showed' it after all the text boxes had been created. So there shouldn't have been any way you could see it "building up a line of textboxes at a time" because it was coded to do that 'invisibly'.
Here are the comparative figures for the code I posted (timed from the start of the code to showing the fully-populated grid):
LB 4.5.0: approx. 1.2 seconds LBB 3.04: approx. 1.5 seconds
So as I said LBB is indeed a little slower, but (on my PC at least) there isn't anything like the difference that you reported, and LB 4.5.0 is far from "instant".
Richard.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #22 on: May 23rd, 2016, 4:36pm » |
|
Richard
I don't think we are really disagreeing on the first point. Cundo only took his code so far, for numeric entry. He didn't need to consider how the entered numbers would be accessed. If he had, he may have changed it to row/col handles (but then again, he may not). I just think that it would be easier to do it with row/col handles. I'm not critising his code nor your comments, just pointing out my own preference.
In respect of the second point. Ignore all that I said. I made some adjustments to the code and unfortunately missed out _WS_VISIBLE and this is the cause of the problem. Reinstating this shows that there is very little difference in the time to display the grid.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #23 on: May 25th, 2016, 4:59pm » |
|
on May 23rd, 2016, 10:00am, RNBW wrote:Whilst the code does enable a grid to be set up in LB, using it with LBB is a bit slow setting up. Also, the fact that a list of 90 textbox controls is set up (1-90) it is not going to be as easy to access the controls as using the grid I have previously set up with RR help where the controls are accessed via row,col.
|
|
I have tried to set up Cundo's code using controls in a row/col basis instead of just a long list of controls. I have first set it up to display headers in Row 1 for the columns and Column 1 for the rows. Then tried to set up reading from the other textboxes and printing to the main window. This works but both the grid and the printed data flashes. It seems to be related to the Timer. If you increase the timer value the rate of flash slows. I've played around with various alternatives to contentName$ and h$, to try to get outside the chkInput loop, but it doesn't work. What am I doing wrong?
Code:
'=========================================
' NumInputGrid_LB_LBB_1F.bas
'=========================================
' Sets up Grid of textboxes
' Works by setting up each textbox as a
' pop-up window and then showing them on
' a child window
' Initial Code by Cundo on Liberty Basic
' Forum 20 May 2016 #reply 17
'=========================================
'NoMainWin
'--------------------------
' Set up #main window size
'--------------------------
maxRows = 10: maxCols =9
dim disp$(maxRows,maxCols)
WindowWidth = 1000
WindowHeight = 480
UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)
'------------------
' OPEN THE #main WINDOW
'------------------
stylebits #main, 0, _WS_VISIBLE, 0, 0
Open "Window" for Window_nf as #main
#main "trapclose [quit]"
'-------------------------
' CREATE THE CONTROLS
'-------------------------
for row = 1 to maxRows
for col = 1 to maxCols
textbox #temp.t1,(100*col)-100+50, (25*row)-25+50,100+1,25+1
stylebits #temp.t1, _ES_RIGHT, _WS_VISIBLE OR _WS_BORDER, 0, 0
Open "" for Window_popup as #temp
maphandle #temp.t1, "#";row;col;".t1" ' required for LBB
maphandle #temp, "#";row;col
next col
next row
'------------------------------------------------------
'attach the controls to the main handler and show them
'------------------------------------------------------
for row = 1 to maxRows
for col = 1 to maxCols
h$= "#";row;col;".t1"
call setParent hWnd(#main) , hWnd(#h$)
call ShowWindow hWnd(#h$), 1
next col
next row
call ShowWindow hWnd(#main), 1
[chkInput]
Timer 0
for row = 1 to maxRows
for col = 1 to maxCols
controlName$="#";row;col;".t1"
#controlName$ "!contents? txt$"
new$= remchar$(txt$,"abcdefghijklmn?opqrstuvwxyz")
if new$<>txt$ Then
#controlName$ new$
handle = Hwnd(#controlName$)
pos = Len(txt$)
CallDLL #user32, "SendMessageA",_
handle As long, _
_EM_SETSEL As long,_
pos As long,_
pos As long,_
result As void
End if
next col
next row
Timer 300, [chkInput]
'----------------------------------
' PRINT ROW NUMBER IN FIRST COLUMN
'----------------------------------
for row = 2 to maxRows
h$ = "#";row;1;".t1"
#h$ "Row ";row-1
next row
'-----------------------------------
' PRINT COLUMN NUMBERS IN FIRST ROW
'-----------------------------------
for col = 2 to maxCols
h$ = "#";1;col;".t1"
#h$ "Col ";col-1
next col
'--------------------
' GET DATA FROM GRID
'--------------------
for row = 2 to maxRows
for col = 2 to maxCols
controlName$="#";row;col;".t1"
#controlName$ "!contents? txt$"
disp$(row,col) = txt$
print txt$
next col
next row
wait
[quit]
close #main
for row = 1 to maxRows
for col = 1 to maxCols
h$= "#";row;col
closeMePlease$ = h$
close #closeMePlease$
next col
next row
end
sub setParent parent,child
calldll #user32, "SetParent",_
child as ulong,_
parent as ulong,_
r as void
End sub
Sub ShowWindow hWnd, flag
'SW_HIDE = 0
'SW_NORMAL = 1
CallDLL #user32, "ShowWindow",hWnd as uLong, flag As Long, r As void
End Sub
'include lb45func.bas
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: Numeric entry into a textbox
« Reply #24 on: May 25th, 2016, 5:54pm » |
|
on May 25th, 2016, 4:59pm, RNBW wrote: The code is working as designed, as far as I can see. You are rejecting any non-numeric characters in the boxes, so when you print (say) "Col 4" to a box the "Col" part fails the validity-check and it gets replaced with just "4"; similarly with the "Row n" boxes.
If your intention was that the row and column 'label' boxes should not be subject to the numeric-character-only check then you should exclude them from it, for example by changing the looping code as follows:
Code: for row = 2 to maxRows
for col = 2 to maxCols But I would say the real problem is a poor choice of array indices. In my opinion it would make much more sense to number the 'label' boxes as column 0 and row 0, and then the 'active' part of the grid would start at column 1 and row 1.
I've made that change in the listing below, and - since this is a support forum for LBB - I've modified the code to use the nicer (and faster) LBB method rather than the LB method. I think we've pretty much established that maintaining compatibility with LB has no value.
Code:'=========================================
' NumInputGrid_LBB_1F.bas
'=========================================
' Sets up Grid of textboxes
' This version is LBB only
' Forum 20 May 2016 #reply 17
'=========================================
NoMainWin
'--------------------------
' Set up #main window size
'--------------------------
maxRows = 10: maxCols = 8
dim disp$(maxRows,maxCols)
WindowWidth = 1000
WindowHeight = 480
UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)
'-------------------------
' CREATE THE CONTROLS
'-------------------------
for row = 0 to maxRows
for col = 0 to maxCols
textbox #main.tb,100*col+50, 25*row+50,100+1,25+1
stylebits #main.tb, _ES_RIGHT, _WS_BORDER, 0, 0
maphandle #main.tb, "#main.tb";row;"x";col
next col
next row
'------------------
' OPEN THE #main WINDOW
'------------------
stylebits #main, 0, _WS_VISIBLE, 0, 0
Open "Window" for Window_nf as #main
#main "trapclose [quit]"
call ShowWindow hWnd(#main), 1
'----------------------------------
' PRINT ROW NUMBER IN FIRST COLUMN
'----------------------------------
for row = 1 to maxRows
h$ = "#main.tb";row;"x0"
#h$ "Row ";row
next row
'-----------------------------------
' PRINT COLUMN NUMBERS IN FIRST ROW
'-----------------------------------
for col = 1 to maxCols
h$ = "#main.tb0x";col
#h$ "Col ";col
next col
[chkInput]
Timer 0
for row = 1 to maxRows
for col = 1 to maxCols
controlName$="#main.tb";row;"x";col
#controlName$ "!contents? txt$"
new$= remchar$(txt$,"abcdefghijklmn?opqrstuvwxyz")
if new$<>txt$ Then
#controlName$ new$
handle = Hwnd(#controlName$)
pos = Len(txt$)
CallDLL #user32, "SendMessageA",_
handle As long, _
_EM_SETSEL As long,_
pos As long,_
pos As long,_
result As void
End if
next col
next row
Timer 300, [chkInput]
'--------------------
' GET DATA FROM GRID
'--------------------
for row = 1 to maxRows
for col = 1 to maxCols
controlName$="#main.tb";row;"x";col
#controlName$ "!contents? txt$"
disp$(row,col) = txt$
print txt$
next col
next row
wait
[quit]
close #main
end
Sub ShowWindow hWnd, flag
'SW_HIDE = 0
'SW_NORMAL = 1
CallDLL #user32, "ShowWindow",hWnd as uLong, flag As Long, r As void
End Sub
'include lb45func.bas Richard.
|
|
|
|
RNBW
Full Member
member is offline


Gender: 
Posts: 106
|
 |
Re: Numeric entry into a textbox
« Reply #25 on: May 25th, 2016, 6:42pm » |
|
Richard
Thank you for your response.
There remains a problem. If you REM NoMainwin. The print txt$ in the GET DATA routine should print out the results to the mainwin. These continue to flash as the data is input into the grid (I reduced the number of rows/cols to 3/4 so not too much data) and to scroll. When all data is entered, the flashing and scrolling does not end until the top window is closed just leaving the mainwin. The data displayed is in excess of what should be seen and always seems to start with 24.
I'm scratching my head.
|
|
Logged
|
|
|
|
|