Seite 1 von 1
GetGadget
Verfasst: 18.09.2011 14:18
von Martin66119
Eine wirkliche Anfängerfrage!
Mit GetGadgetText lese ich eine FloatZahl(d.h. ein String) ein . Z.B. 1.234
Die Stringvariable wandle ich nun mit ValF um.
Nun möchte ich aber sicherstellen, dass bei der Eingabe nur "." und kein "," akzeptiert wird. D.h. ich möchte nur die Ziffern 0 - 9 sowie den . als Dezimalpunkt zulassen. Gibt es da eine Funktion für oder muss man das selbst programmieren. Bestimmt gibt es dafür aber schon ein Beispiel.
Grüße
Martin
Re: GetGadget
Verfasst: 18.09.2011 14:40
von CSHW89
Also wenn du nur Zahlen erlauben willst, dann ginge #PB_String_Numeric als Flag fürs StringGadget. Mit dem Punkt ist das schon ne Ecke schwieriger, dafür gibt es KeyboardHook. Damit kann man die Eingabe soweit einschränken, dass man nur bestimmte Tasten benutzen darf. Dabei muss man aber auch an Tasten denken wie z.b. die Pfeiltasten. Sonst kann man im StringGadget nicht mehr navigieren.
Hier mal ein Beispielcode aus dem CodeArchiv, scheint ganz gut zu funktionieren:
Code: Alles auswählen
; English forum: http://www.purebasic.fr/english/viewtopic.php?t=8500&highlight=
; Author: TeddyLM (updated for PB4.00 by blbltheworm)
; Date: 26. November 2003
; OS: Windows
; Demo: No
;============================
;StringGadget with KEY-FILTER
;Thanks to Art Sentinel for the Hook-Tutorial
;============================
Global hhook
Global hookValue.b : hookValue = 0
Global CommaPoint.b : CommaPoint = 0
#StringID1 = 11
#StringID2 = 14
;************
;PROCEDURES
;************
Procedure KeyboardProc(nCode, wParam, lParam)
Define.b Result
If wParam < 31
Result = 0
ElseIf wParam = 190 And CommaPoint = 0 ;"."
Result = 0
ElseIf wParam = 8 ;Del
Result = 0
ElseIf wParam = 37 ;ArrowLeft
Result = 0
ElseIf wParam = 38 ;ArrowUp
Result = 0
ElseIf wParam = 39 ;ArrowRight
Result = 0
ElseIf wParam = 40 ;ArrowDown
Result = 0
ElseIf wParam = 46 ;Entf
Result = 0
ElseIf wParam = 48 ;0
Result = 0
ElseIf wParam = 49 ;1
Result = 0
ElseIf wParam = 50 ;2
Result = 0
ElseIf wParam = 51 ;3
Result = 0
ElseIf wParam = 52 ;4
Result = 0
ElseIf wParam = 53 ;5
Result = 0
ElseIf wParam = 54 ;6
Result = 0
ElseIf wParam = 55 ;7
result = 0
ElseIf wParam = 56 ;8
Result = 0
ElseIf wParam = 57 ;9
Result = 0
Else
Result = 1
EndIf
ProcedureReturn Result
EndProcedure
;***********
;***********
Procedure HookProc(Hooked)
Shared hhook
Shared CommaPoint
Select Hooked
Case 1
hInstance = GetModuleHandle_(0)
lpdwProcessId = GetWindowThreadProcessId_(WindowID, 0)
hhook = SetWindowsHookEx_(#WH_KEYBOARD, @KeyboardProc(), hInstance, lpdwProcessId)
Case 0
UnhookWindowsHookEx_(hhook)
EndSelect
EndProcedure
;************
;************
WindowID = OpenWindow(0, 150, 150, 300, 300, "Decimal-Filter (Thanks to Art Sentinel)", #PB_Window_SystemMenu)
If WindowID <> 0
TextGadget(10, 50, 96, 180, 22, "No Filter :")
StringGadget(#StringID1, 50, 120, 180, 22, "") : SendMessage_(GadgetID(#StringID1), #EM_LIMITTEXT, 20, 0)
TextGadget(12, 50, 166, 180, 22, "Filter Decimal-Value :")
StringGadget(#StringID2, 50, 190, 180, 22, "") : SendMessage_(GadgetID(#StringID2), #EM_LIMITTEXT, 20, 0)
SetActiveGadget(#StringID1)
;Main loop
Repeat
Select WaitWindowEvent()
Case #WM_KEYDOWN
If EventwParam() = 13
Select EventGadget()
Case #StringID1
text$ = GetGadgetText(#StringID2)
SendMessage_(GadgetID(#StringID2), #EM_SETSEL, 0, Len(text$))
SetActiveGadget(#StringID2)
Case #StringID2
text$ = GetGadgetText(#StringID1)
SendMessage_(GadgetID(#StringID1), #EM_SETSEL, 0, Len(text$))
SetActiveGadget(#StringID1)
EndSelect
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case #StringID2
Text$=GetGadgetText(#StringID2)
StLength = Len(Text$)
CommaPoint = 0
If StLength > 0
For counter = 1 To StLength
If Mid(Text$,counter,1) = "."
CommaPoint = CommaPoint + 1
EndIf
Next
EndIf
If hookValue = 0 : hookValue = 1 : HookProc(1) : EndIf
Default
If hookValue = 1 : hookValue = 0 : HookProc(0) : EndIf
EndSelect
Case #WM_CLOSE
Quit = 1
EndSelect
Until Quit = 1
EndIf
End
;============================
lg Kevin
Re: GetGadget
Verfasst: 18.09.2011 18:46
von Martin66119
Vielen Dank für die Hilfe.
Das mit #PB_String_Numeric hatte ich gelesen. Da steht aber "Nur (positive) Ganzzahlen werden akzeptiert." und das ganze soll mit allen float zahlen klappen.
Grüße
Martin
Re: GetGadget
Verfasst: 18.09.2011 19:06
von NicTheQuick
Du kannst auch sowas hübsches hier machen:
Code: Alles auswählen
Procedure isFloat(text.s)
If CreateRegularExpression(0, "^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$")
If MatchRegularExpression(0, text)
ProcedureReturn #True
EndIf
Else
Debug RegularExpressionError()
EndIf
ProcedureReturn #False
EndProcedure
If OpenWindow(0, 0, 0, 200, 30, "Test", #PB_Window_ScreenCentered)
StringGadget(0, 0, 0, 200, 30, "")
SetGadgetColor(0, #PB_Gadget_BackColor, RGB(255, 127, 127))
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case 0
If (EventType() = #PB_EventType_Change)
If (Not isFloat(GetGadgetText(0)))
SetGadgetColor(0, #PB_Gadget_BackColor, RGB(255, 127, 127))
Else
SetGadgetColor(0, #PB_Gadget_BackColor, -1)
EndIf
EndIf
EndSelect
EndSelect
ForEver
EndIf
Mit diesem regulären Ausdruck gehen auch Exponenten.
Re: GetGadget
Verfasst: 18.09.2011 19:27
von Martin66119
Danke Nic,
werde schauen wie ich damit Zahlen einlesen kann.
Martin
Re: GetGadget
Verfasst: 18.09.2011 23:49
von hjbremer
ein Beispiel mit Callback
Code: Alles auswählen
Enumeration
#mainwindow
EndEnumeration
Structure Eingabefelder
Array inputGadgetpbnr.i(0)
anzahlfelder.i
callbackoriginal.i
EndStructure
EnableExplicit
Define *input.Eingabefelder = AllocateMemory(SizeOf(Eingabefelder))
Procedure InputCallback(hwnd, msg, wParam, lParam)
;hwnd ist hier gleich der ID vom StringGadget
Protected *p.Eingabefelder = GetWindowLongPtr_(hwnd, #GWL_USERDATA)
If msg = #WM_CHAR
Select wparam
Case 8, 45, 48 To 57 ;Backspace, Minus, Zahlen
Case 44: wparam = 46 ;Komma wird Punkt
Default: wparam = 0 ;Alles andere ist verboten
EndSelect
EndIf
ProcedureReturn CallWindowProc_(*p\callbackoriginal, hwnd, msg, wParam, lParam)
EndProcedure
Define j, ze, event
OpenWindow(#mainwindow, 0, 0, 150, 150, "Main", #PB_Window_ScreenCentered |#PB_Window_SystemMenu)
With *input
\anzahlfelder = 3
Dim \inputGadgetpbnr(\anzahlfelder)
ze = 10
For j = 1 To \anzahlfelder
\inputGadgetpbnr(j) = StringGadget(#PB_Any, 10, ze, 80, 22, "")
ze + 30
\callbackoriginal = GetWindowLongPtr_(GadgetID(\inputGadgetpbnr(j)), #GWL_WNDPROC)
SetWindowLongPtr_(GadgetID(\inputGadgetpbnr(j)), #GWL_WNDPROC, @InputCallback())
SetWindowLongPtr_(GadgetID(\inputGadgetpbnr(j)), #GWL_USERDATA, *input)
;lfdnr einsetzen zur Unterscheidung im Callback, falls benötigt
;SetGadgetData(\inputGadgetpbnr(j), j)
Next
EndWith
Repeat
event = WaitWindowEvent()
Select EventWindow()
Case #mainwindow
;tue irgendwas
EndSelect
Until Event = #PB_Event_CloseWindow