Page 2 of 5

Re: Formatting Numeric Input

Posted: Fri Apr 13, 2018 5:09 pm
by RNBW
RNBW wrote: โ†‘Thu Apr 12, 2018 5:18 pm This is a bit more advanced than the previous examples. The program sets up a grid into which you can enter numbers ( - . 0 to 9 ). It carries out a check as you enter each individual character. If it's a valid number it accepts it. If it's not valid, you will see the character very briefly before it's deleted. Press tab to move to next cell to right and Shift+Tab to move to cell to left.
I've managed to change the code so that it now ensures that there is only one period "." in the number. The only areas of validation that it doesn't cover are exponential numbers (which personally I'm not bothered about), which someone may wish to include and also the issue of "." at the end of a number. It would be nice to put one or two zeros after this, but I don't seem to be able to get my head around it. Perhaps someone could help here.

I have produced the code for a grid of textboxes, but if someone wants to simplify it and produce code say for one textbox that may be helpful to beginners.

Code: Select all

'===============================================
' FILENAME: NumericInputInAGrid_03.bas 
'-----------------------------------------------
'Currently this works fine including restricting
'to only one minus sign "-" at the start of the 
'number and one period ".". 
'===============================================

NoMainWin        
    Row = 10: Col =9
    Dim TB$(Row, Col)
    WindowWidth = 1000
    WindowHeight = 400
    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    bWidth = 100: bHt = 30  'width & height of textboxes

    'Sets up the grid of Textboxes
    TextboxColor$ = "white"
    print: print
    For i = 1 to Row
       For j = 1 to Col  
           Stylebits #main.tb, _ES_RIGHT, _WS_BORDER, 0, 0
           TextBox #main.tb, (bWidth)*j -100+20, (bHt)*i - 15, bWidth+1, bHt+1
           TB$(i,j) = "#main.tb"; "_r";i;"c";j           
           'print TB$(i,j)   ' prints out handles on main win if you REM nomainwin
           maphandle #main.tb, TB$(i,j)
       Next
    Next

    Open "untitled" For Window As #main
    #main, "Font Arial 11"
    #main "TrapClose Quit"

While Hwnd(#main)
    Scan
    For i = 1 To Row
       For j = 1 to Col                    
         Call checkInput TB$(i,j)         
       Next j 
    Next i
    CallDLL #kernel32, "Sleep", 300   As long, _
                                ret As void  
Wend

'---------------------------------------------------------------
' Check the characters entered.
'---------------------------------------------------------------
Sub checkInput controlName$
    #controlName$ "!contents? txt$"
    initLen = Len(txt$)
    txt$ = num$(txt$)
    If Len(txt$) < initLen Then
        #controlName$ txt$
        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
End Sub

'------------------------
' Close down the program
'------------------------
Sub Quit handle$
    Close #handle$
    End
End Sub

'-------------------------------------------------------------
' function to replace remchar$() LB4.5 function
' This should make this compatible with earlier version of LB
' Code by GaRPMorE in Re: textbox input - numbers only
' in LB Forum Reply #6 on: Apr 22nd, 2016, 7:23pm ยป
'-------------------------------------------------------------
function num$(d$)
    t = 0
    for i=1 to len(d$)
        a=asc(mid$(d$,i,1))
        if a = 46 then t = t + 1
        if t > 1 then a = 8
        if a = 45 and i = 1 or a = 46 or a>47 and a<58 then num$=num$+chr$(a)
        ' chr$(46) = "." 
    next
end function 

Re: Formatting Numeric Input

Posted: Fri Apr 13, 2018 7:34 pm
by tsh73
I would say code is surprisingly small comparing to that it does.
Nice work.

Re: Formatting Numeric Input

Posted: Sat Apr 14, 2018 9:27 am
by RNBW
tsh73
The compactness of the code is due to LBB, for which we should thank Richard Russell. Also, Richard provided the basis of the construction of the textbox grid. The function is made up of a pretty standard way of checking character input for numbers. I found the few lines that sort out prevention of double "-" and "." on the FreeBASIC forum. I must say I'm quite pleased with it. If anyone wants to include checking for exponential numbers, I'm sure they would find it reasonably easy to adapt.
Thank you for your kind words, it is appreciated.

Re: Formatting Numeric Input

Posted: Sat Apr 14, 2018 10:52 am
by tsh73
about leading '0' and trailing '.'
I think it makes sense to fix on leaving the cell.
I don't know how this event could be hooked - but at least there is a way to check if cell has focus or not.
So if it doesn't have focus you can do extra check and change say '0025.' to '25' or '25.0'.

Re: Formatting Numeric Input

Posted: Sat Apr 14, 2018 1:27 pm
by RNBW
tsh73
Ultimately, I would be looking to solve such issues by providing a final output with using(). This would enable the user to have as many characters after the decimal point as required. Leading zeros could be removed by using trim$. Although, in the subject matter that I would be using it, it is extremely unlikely that a number would be entered with leading zeros, other than 0.15. The user wouldn't enter 00.15 (at least I've never come across anyone who did that - but not impossible - nothing is).
I shelved all my related code a while ago and changed computers, so I've got to do some delving to find it, or work it out all over again. My brain's not as sharp as it used to be (old age and all that!).

Re: Formatting Numeric Input

Posted: Sat Apr 14, 2018 2:05 pm
by guest
RNBW wrote: โ†‘Sat Apr 14, 2018 1:27 pm Ultimately, I would be looking to solve such issues by providing a final output with using().
Of course LBB supports an enhanced USING(), compared with LB 4; you can find details at the wiki here.

Richard.

Re: Formatting Numeric Input

Posted: Sat Apr 14, 2018 4:03 pm
by RNBW
Richard
Thanks for reminding me. I'd forgotten that LBB has a 'proper' using() function. I was going to look for a work-around.
Ray

Re: Formatting Numeric Input

Posted: Sun Apr 15, 2018 10:30 pm
by RNBW
It's quite late, but here is a snippet of code to produce filtered numeric entry into a textbox.
It prevents double entry of "-" and "." and ensures "-" can only be entered as the first character.
It does not address the issue of the final character being "." and whether a zero(s) should automatically follow.
It is Liberty Basic compatible.

Code: Select all

'===============================================
' Numeric entry into a textbox.
' This permits the entry of numbers including
' "-" and ".".  It also prevents more than one
' "-" and "." from being entered.
' It does not address "." as the last character
' entered.
'===============================================

nomainwin  ' this prevents the main window opening
textbox #main.textbox, 10, 50, 100, 25  'sets up a textbox.  #main.textbox is its handle
WindowWidth = 350  ' window size
WindowHeight = 150

open "Filtered Numeric Input" for window as #main  ' opens window
#main.textbox, "!font Arial_Bold, 10"
#main.textbox "!contents? txt$"    'gets the text in the textbox
#main.textbox "!setfocus"
#main "trapclose [quit]"     'closes the window

[CheckInput]       ' label
timer 0

    #main.textbox "!contents? txt$"   'text in textbox
     oldtxt$ = txt$    ' make text the oldtext
    txt$ = num$(txt$)  ' gets new text from function num$(text$) which does the checking
    if oldtxt$ <> txt$ then
        #main.textbox txt$      ' if old text is not the same as the new text then use new text
        handle = hWnd(#main.textbox)   ' get the handle of the textbox
        pos = len(txt$)    ' position of character is the length of the current text
        calldll #user32, "SendMessageA", _   ' call EM_SETSEL
            handle as ulong, _
            _EM_SETSEL as long, _
            pos as long, _
            pos as long, _
            result as void
    end if

timer 300, [CheckInput]  ' short delay then last char is deleted if not 0-9, - or .
wait   ' wait for event

' Function to check that character input is 0-9, - or .
function num$(d$)
    t = 0: t1 =0
    for i=1 to len(d$)
        a=asc(mid$(d$,i,1))
        if a = 46 then t = t + 1
        if t > 1 then a = 8
        if a = 45 and i>1 then a = 8
        
        
        if a = 46 and i = 1 then num$ = "0" + num$
        if a = 45 or a = 46 or a>47 and a<58 then num$=num$+chr$(a)
    next

end function

[quit]
close #main   ' close window
end

Re: Formatting Numeric Input

Posted: Sun Apr 15, 2018 10:50 pm
by guest
RNBW wrote: โ†‘Sun Apr 15, 2018 10:30 pm It's quite late, but here is a snippet of code to produce filtered numeric entry into a textbox.
I don't understand this code:

Code: Select all

        if a = 45 and i>1 then a = 8
        if a = 45 then t1 = t1 + 1
        if t1 > 1 then a = 8
Superficially it seems to be ensuring that a minus sign can only appear as the first character and that there is no more than one minus sign. But if a minus sign can only appear as the first character, there can never be more than one anyway! Am I missing something?

Also, switching between characters and numbers and then back to characters again makes your program messy and hard to follow. Presumbly you're doing that because you are hoping it will be faster as a result, but is it? Have you actually compared the speed with the more straightforward and obvious approach?

Richard.

Re: Formatting Numeric Input

Posted: Mon Apr 16, 2018 2:42 pm
by RNBW
Hi Richard. It wa slate when I was writing the code. There is of course a superfluous line which I left in, which resulted in a double check on more than one "-".

I have edited the code and removed the unnecessary line, leaving a blank line in its place.

Thank you for spotting it.