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