Numeric entry with commas into Textbox

Discussions about the Liberty BASIC language, with particular reference to LB Booster
RNBW
Posts: 85
Joined: Thu Apr 05, 2018 9:21 pm

Numeric entry with commas into Textbox

Post by RNBW »

This came from ChatGPT, with some minor changes from me.

It will display delimiting commas as you type (e.g. 123456.789 will appear as 123,456.789). It inserts commas in the integer part of a number only.
If you type in .123 it will display as 0.123 and if you type in -.123 it will display as -0.123.
This all happens as you are typing the characters.

Within the code, you can replace the comma with a space and it will display as 123 456.789, if this is how your country displays numbers.

The code does ramble a bit and I'm sure someone could come up with code that does the same thing more concisely. There was also a lot of toing and froing with ChatGPT to get rid of errors in syntax etc.

Here is the code:

Code: Select all

'=== Liberty BASIC: Right-justified numeric entry with minus, decimal, and auto-commas ===
'nomainwin

WindowWidth  = 380
WindowHeight = 180
UpperLeftX   = 200
UpperLeftY   = 200

' Right-justify style before creating textbox
stylebits #main.tbNum, _ES_RIGHT, 0, 0, 0

statictext #main.lbl, "Enter number:", 20, 12, 150, 20
textbox    #main.tbNum, 20, 40, 260, 25
button     #main.btnGet, "Get Number", [GetNumber], UL, 20, 80, 100, 25
button     #main.btnClose, "Close", [Quit], UL, 210, 80, 70, 25

open "Number Entry (Auto Comma)" for window as #main
print #main, "trapclose [Quit]"
print #main.tbNum, "!setfocus"
print #main.tbNum, "!font Arial bold 12"

' Poll the textbox every 100ms
timer 100, [CheckInput]
wait

[CheckInput]
print #main.tbNum, "!contents?"
input #main.tbNum, raw$

'=== Filter input: allow only one leading minus, digits, and one decimal point ===
filtered$ = ""
decimalSeen = 0
minusSeen = 0

for i = 1 to len(raw$)
    ch$ = mid$(raw$, i, 1)
    select case
        case ch$ = "-" and i = 1 and minusSeen = 0
            filtered$ = filtered$ + "-"
            minusSeen = 1
        case instr("0123456789", ch$) > 0
            filtered$ = filtered$ + ch$
        case ch$ = "." and decimalSeen = 0
            filtered$ = filtered$ + "."
            decimalSeen = 1
    end select
next

'=== Format with commas ===
integerPart$ = filtered$
decimalPart$ = ""

dotPos = instr(filtered$, ".")
if dotPos > 0 then
    integerPart$ = left$(filtered$, dotPos - 1)
    decimalPart$ = mid$(filtered$, dotPos) ' keep decimal point + fraction
end if

sign$ = ""
if len(integerPart$) > 0 and left$(integerPart$, 1) = "-" then
    sign$ = "-"
    integerPart$ = mid$(integerPart$, 2)
end if

' Only force a leading zero when a decimal point is present (decimalSeen = 1)
if integerPart$ = "" then
    if decimalSeen = 1 then integerPart$ = "0"
end if

' Insert commas or spaces into integer part
formattedInt$ = ""
lenInt = len(integerPart$)
count = 0
for i = lenInt to 1 step -1
    count = count + 1
    formattedInt$ = mid$(integerPart$, i, 1) + formattedInt$
    if count mod 3 = 0 and i > 1 then
        formattedInt$ = "," + formattedInt$
        'formattedInt$ = " " + formattedInt$
    end if
next

' Keep fractional part exactly as typed
final$ = sign$ + formattedInt$ + decimalPart$

if final$ <> raw$ then
    print #main.tbNum, final$
    h = hwnd(#main.tbNum)
    p = len(final$)
    call SetCaretToEnd h, p
end if

wait

[GetNumber]
' Get number from textbox as typed (string)
print #main.tbNum, "!contents?"
input #main.tbNum, text$

' Remove commas or spaces
clean$ = replace$(text$, ",", "")
'clean$ = replace$(text$, " ", "")

' Show the exact typed value
print "Exact value entered: "; clean$

' Convert to numeric for calculations
num = val(clean$)

' Determine how many decimal places were typed
decPos = instr(clean$, ".")
if decPos > 0 then
    decCount = len(clean$) - decPos
else
    decCount = 0
end if

wait

[Quit]
timer 0
close #main
end

'=== API helper to set caret position ===
sub SetCaretToEnd hCtrl, pos
    calldll #user32, "SendMessageA", _
        hCtrl as ulong, _
        177 as long, _         ' EM_SETSEL constant
        pos as long, pos as long, _
        r as long
end sub

'=== String replace function ===
function replace$(src$, find$, repl$)
    new$ = ""
    p = 1
    while p <= len(src$)
        if mid$(src$, p, len(find$)) = find$ then
            new$ = new$ + repl$
            p = p + len(find$)
        else
            new$ = new$ + mid$(src$, p, 1)
            p = p + 1
        end if
    wend
    replace$ = new$
end function
I hope someone finds it useful.
sarmednafi
Posts: 38
Joined: Fri Apr 06, 2018 6:27 am

Re: Numeric entry with commas into Textbox

Post by sarmednafi »

Hi RNBW,

I wonder why you mentioned "Right-justified"?
Right-justified means Right Alignment, as it is in Microsoft. Do you mean Text direction?
Text direction makes a big difference in Microsoft.
Actually, I don't know how to change the text direction from left to right to right to left using LB or LBB.
I removed the sentence "stylebits #main.tbNum, _ES_RIGHT, 0, 0, 0"
The code works fine.

Would you please describe this point?
All the Best
Sarmed Nafi
RNBW
Posts: 85
Joined: Thu Apr 05, 2018 9:21 pm

Re: Numeric entry with commas into Textbox

Post by RNBW »

sarmednafi wrote: Sat Oct 11, 2025 3:36 am Hi RNBW,

I wonder why you mentioned "Right-justified"?
Right-justified means Right Alignment, as it is in Microsoft. Do you mean Text direction?
Text direction makes a big difference in Microsoft.
Actually, I don't know how to change the text direction from left to right to right to left using LB or LBB.
I removed the sentence "stylebits #main.tbNum, _ES_RIGHT, 0, 0, 0"
The code works fine.

Would you please describe this point?
All the Best
Sarmed Nafi
Hi sarmednafi
I'm afraid it is my misuse of the English Language and what I have been brought up using. The correct term is right-aligned. As you will see when you removed the Stylebits statement it became left-aligned. The code works the same whether it be left- or right-aligned. The caret remains at the right of the inputted characters when you are entering characters. All the Stylebits statement does it right-align the characters in the textbox. The default (without Stylebits) is left-aligned.
I hope this clarifies things for you and that you can make use of the code.
Best regards
Ray
guest
Site Admin
Posts: 227
Joined: Tue Apr 03, 2018 1:34 pm

Re: Numeric entry with commas into Textbox

Post by guest »

sarmednafi wrote: Sat Oct 11, 2025 3:36 am Actually, I don't know how to change the text direction from left to right to right to left using LB or LBB.
In LBB's mainwin you can switch text direction using embedded BBC BASIC code (e.g. using !VDU 23,16,2;0;0;0;) but I'm guessing that's not what you mean.

In Windows controls the text direction is not something that you explicitly set, rather it is determined automatically according to the language in which it is written. This is important, because it means you can have bidirectional text in which LTR and RTL content is mixed, like this:

"This is النص العربي which is written right-to-left"

To make use of this feature in LB or LBB you would need to use Unicode controls in your program, rather than the ANSI controls which are used by default. You can do that (in principle, anyway) using CALLDLL, but it's not something which is specifically supported.

By contrast, BBC BASIC for Windows (on which LBB is based) does fully support bi-directional text (with care); so does BBC BASIC for SDL 2.0 although not currently in the supplied libraries, e.g. dlglib.bbc and editbox.bbc.

It would theoretically be possible, for example SDLIDE.bbc (one of the two supplied IDEs) does support bi-directional text in the program editor, but transplanting that support into the BBCSDL libraries would be quite difficult, and it's now unlikely that I will attempt it.