GetGadget

Anfängerfragen zum Programmieren mit PureBasic.
Martin66119
Beiträge: 282
Registriert: 03.01.2005 11:36

GetGadget

Beitrag 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
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: GetGadget

Beitrag 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
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Martin66119
Beiträge: 282
Registriert: 03.01.2005 11:36

Re: GetGadget

Beitrag 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
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: GetGadget

Beitrag 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.
Martin66119
Beiträge: 282
Registriert: 03.01.2005 11:36

Re: GetGadget

Beitrag von Martin66119 »

Danke Nic,

werde schauen wie ich damit Zahlen einlesen kann.

Martin
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: GetGadget

Beitrag 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 
            
   
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Antworten