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