Check each character as it is entered to ensure that:
• The character was limited to 0 to 9, minus and decimal point (period)
• Minus can only occur as the first character entered
• There can only be one occurrence of minus
• There can only be one occurrence of a decimal point
• If the first character entered is a decimal point (.123) it will be displayed as 0.123
• If the first character is minus and the second a decimal point (-.123) it will be displayed as -0.123
• The display will be right justified
• It must be editable
I couldn’t find code that did all of these, but was able to find two that came close. I have amalgamated the two. Credit is given in the code to the writers of the original code. I am very grateful to them and I hope that the code below will be useful. I shall be grateful if anyone can improve it or put me right if I have got anything wrong.
Code: Select all
;--------------------------------------------------------------------------------------------
; Numeric input
;---------------------------------------------------------------------------------------------
; This is an amalgamation of two programs. One from Danilo
; included in RSBasic's WinAPI Library (StringGadget section)
; and BasicallyPure's program in the Purebasic forum
; (https://www.purebasic.fr/english/viewtopic.php?f=13&t=50565&hilit=Numeric+entry&start=0)
; It accepts characters 0 to 9 minus and period.
; It accepts a minus only as the first character.
; It only accepts one minus sign and one period in the entry.
; An entry of .123 displays as 0.123
; An entry of -.123 is displayed as -0.123
; The amalgamation of code has been produced by RNBW, who is grateful
; to all the contributors to the code:
; Danilo
; BasicallyPure
; asked for by 'akee'
; inspired by 'IdeasVacuum'
; key assist from 'Shardik'
;---------------------------------------------------------------------------------------------
EnableExplicit
Procedure.s CheckNumeric(iStrGadget.i)
;purpose: limit StringGadget to accept only numeric input
;with support for floating poing characters: . - + E e
Protected.i iCount, iTextLength, iAccept, iDecimal, iExp, iNeg
Protected.s sNewText, sChar, sGadgetText
sGadgetText = GetGadgetText(iStrGadget)
iTextLength = Len(sGadgetText)
For iCount = 1 To iTextLength
sChar = Mid(sGadgetText, iCount, 1)
iAccept = #False
Select Asc(sChar)
Case 48 To 57 ; Accepted numbers
iAccept = #True
If iExp = 1 : iExp + 1 : EndIf
Case 43, 45 ; Minus or Plus sign
If iCount = 1
iAccept = #True : iNeg = 1
ElseIf iExp = 1
iAccept = #True : iExp + 1
EndIf
Case 46 ; period
If Not iDecimal And Not iExp
iDecimal = #True : iAccept = #True
If iCount - iNeg = 1 : sChar = "0" + sChar : EndIf
EndIf
Case 69, 101 ; 'e' or 'E'
If Not iExp And iCount > 1 + iNeg
iExp = 1 : iAccept = #True
EndIf
EndSelect
If iAccept : sNewText + sChar : EndIf
Next
SetGadgetText(iStrGadget, sNewText)
iTextLength = Len(sNewText)
;windows only
SendMessage_(GadgetID(iStrGadget),#EM_SETSEL,iTextLength,iTextLength) ;Set cursor to end of string
EndProcedure
If OpenWindow(0,0,0,300,150,"Number of Decimal Places",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StringGadget(1,10,10,200,20,"",#PB_Text_Right)
LoadFont (1, "Monaco", 11, #PB_Font_Bold)
SetGadgetFont(1, FontID(1))
Repeat
Define EventID=WaitWindowEvent()
If EventID=#PB_Event_Gadget
Select EventGadget()
Case 1
If EventType() = #PB_EventType_Change
CheckNumeric(EventGadget())
EndIf
EndSelect
EndIf
If EventID = #PB_Event_CloseWindow
End
EndIf
ForEver
EndIf