Seite 1 von 1

Dezimaleingabe in StringGadget

Verfasst: 15.03.2008 19:14
von NicknameFJ
Hallo zusammen,

ich habe hier im Forum schon des öfteren die Frage gelesen, wie man die Eingabe in ein Stringgadget auf Zahlen beschränken kann.

Ich verwende in meinen Prog´s immer folgende Proceduren (im Code gleich ´ne Demo wie´s funzt eingebaut

Wer´s gebrauchen kann, kann es gerne verwenden.

Verbesserungsvorschläge sind gerne willkommen.

Ähm, ja hätte die Variablen als protected deklarien sollen !


Joachim

Code: Alles auswählen


#MainWindow = 1

Enumeration
  #StringID1  = 10
  #StringID2
EndEnumeration




Structure InputFlags
  Use.b
  Vorzeichen.b
  Vorkomma.b
  Nachkomma.b 
EndStructure


Structure InputParameter
  Gadget.l
  Position.l
  PointPos.l
  length.l
  Sign.b
  Text.s
EndStructure


Global hhook
Global Param.InputParameter,InputFlags.InputFlags




Procedure StringGadgetCursorX(Gadget) 
  SendMessage_(GadgetID(Gadget),#EM_GETSEL,@min,@Max) 
  ProcedureReturn Max-SendMessage_(GadgetID(Gadget),#EM_LINEINDEX,SendMessage_(GadgetID(Gadget),#EM_LINEFROMCHAR,min,0),0)+1 
EndProcedure


Procedure GetParameter(Gadget)
  TempText$      = GetGadgetText(Gadget)
  
  Param\Gadget   = Gadget
  Param\length   = Len(TempText$)
  Param\Position = StringGadgetCursorX(Gadget)-1
  
  Param\PointPos = -1
  Param\Sign     = 0
  Param\Text     = TempText$
  
  If Param\length
    For i =1 To Param\length
      Char$ = Mid(TempText$,i,1)
      
      If Char$ = "." Or Char$ = ","
        Param\PointPos = i
        Break
      EndIf
    Next
    
    If Left(TempText$,1) = "-"
      Param\Sign = 1
    EndIf
    
  EndIf
  
EndProcedure

Procedure NoKeyBoardHookProc(code, wParam, lParam)

  ProcedureReturn 0
  
EndProcedure





Procedure KeyboardProc(code, wParam, lParam)
   
  
  GetParameter(GetActiveGadget())

  result = 1
  
  If lParam >= 0
    UpFlag = 1
  Else
    UpFlag = 0
  EndIf

  If Left(Param\Text,1) = "-"
    SignVersatz = 1
  Else
    SignVersatz = 0
  EndIf
  
  If UpFlag
    If wParam = 8 
      If  Param\Position = Param\PointPos
       
        LinksText$  = Left (Param\Text,Param\Position-1)
        RechtsText$ = Mid(Param\Text,Param\Position+1,InputFlags\Nachkomma)
        Debug LinksText$
        Debug RechtsText$
        
        
          Param\Text = Left(LinksText$+RechtsText$,SignVersatz+InputFlags\Vorkomma)
          SetGadgetText(Param\Gadget,Param\Text)
          SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position-1,Param\Position-1)
          result = 1
        
      Else
        result = 0
      EndIf
      
    ElseIf wParam = 35
      SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\length,Param\length) 
      GetParameter(Param\Gadget)
      
      result = 1
      
    ElseIf wParam = 36
      SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, 0,0)
      
      GetParameter(Param\Gadget)
      
      result = 1
      
    ElseIf wParam = 37 
      SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position-1,Param\Position-1)
      
       GetParameter(Param\Gadget)
       result = 1

      ElseIf wParam = 39 
      SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position+1,Param\Position+1)
      
      GetParameter(Param\Gadget)
      
       result = 1
    ElseIf wParam = 46 
      If  Param\Position+1 = Param\PointPos
        LinksText$  = Left (Param\Text,Param\Position)
        RechtsText$ = Mid(Param\Text,Param\Position+2,InputFlags\Nachkomma)
        Debug LinksText$
        Debug RechtsText$
        
        
        Param\Text = Left(LinksText$+RechtsText$,SignVersatz+InputFlags\Vorkomma)
        SetGadgetText(Param\Gadget,Param\Text)
        SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position,Param\Position)
        
        result = 1
      Else
        result = 0
      EndIf
      
      
      
    ElseIf (wParam = 188 Or wParam = 190) And Param\PointPos = -1 And InputFlags\Nachkomma > 0
       LinksText$  = Left (Param\Text,Param\Position)
       RechtsText$ = Mid(Param\Text,Param\Position+1,InputFlags\Nachkomma)
      
       Param\Text  = LinksText$ + "," + RechtsText$
       SetGadgetText(Param\Gadget,Param\Text)
       SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position+1,Param\Position+1)
      
       result = 1
      
     ElseIf wParam = 189 And InputFlags\Vorzeichen = 1 
       If Left(Param\Text,1) = "-"
        Param\Text = Right(Param\Text,Param\length-1)
        SetGadgetText(Param\Gadget,Param\Text)
        SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position-1,Param\Position-1)
        
         result = 1
      Else
        Param\Text = "-"+Param\Text
        SetGadgetText(Param\Gadget,Param\Text)
        SendMessage_(GadgetID(Param\Gadget),#EM_SETSEL, Param\Position+1,Param\Position+1)
     
         result = 1
       EndIf
     
    
    ElseIf wParam >= 48 And wParam <= 57
      
      
      If Param\Position+1 > Param\PointPos And Param\PointPos <> -1  
        If Param\PointPos + InputFlags\Nachkomma > Param\length
          result = 0
        Else
          result = 1
        EndIf
        
      Else   
        
        If Param\Position < SignVersatz   
           result = 1
        Else   
        
           If Param\PointPos = -1   
            
            If Param\length >= InputFlags\Vorkomma + SignVersatz
                result = 1  
              Else
                result = 0
              EndIf
            
            Else                  
            If Param\PointPos > InputFlags\Vorkomma + SignVersatz 
              result = 1
            Else
              result = 0
            EndIf
           EndIf
        EndIf
      EndIf
      
      
      
    
    
     Else
       result = 1
     EndIf
   EndIf
  ProcedureReturn result
EndProcedure



Procedure HookProc(Hooked)
  Shared hhook
  
    Debug "Hook "+Str(Hooked)

  Select Hooked
    Case 1
      hInstance = GetModuleHandle_(0)
      lpdwProcessId = GetWindowThreadProcessId_(WindowID, 0)
      hhook = SetWindowsHookEx_(#WH_KEYBOARD, @KeyboardProc(), hInstance, lpdwProcessId)
    Case 0
     
      hInstance = GetModuleHandle_(0)
      lpdwProcessId = GetWindowThreadProcessId_(WindowID, 0)
      hhook = SetWindowsHookEx_(#WH_KEYBOARD, @NoKeyBoardHookProc(), hInstance, lpdwProcessId)

     
     
  EndSelect
EndProcedure



WindowID = OpenWindow(0, 150, 150, 300, 300, "Dezimaleingaben in Stringgadget", #PB_Window_SystemMenu)
If WindowID <> 0
  If CreateGadgetList(WindowID(0))
    StringGadget(#StringID1,50,100,180,22,"")
    TextGadget(12, 50, 166, 180, 22, "Dezimaleingabe :")
    StringGadget(#StringID2, 50, 190, 180, 22, "")
    SetActiveGadget(#StringID2)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #StringID2
            
              InputFlags\Vorzeichen = 1
              InputFlags\Nachkomma  = 4
              InputFlags\Vorkomma   = 8
              
              HookProc(1)
            Default
              
              HookProc(0)
          EndSelect
          
          
        Case #WM_CLOSE
          Quit = 1
      EndSelect
    Until Quit = 1
  EndIf
EndIf
End


Verfasst: 15.03.2008 20:06
von edel
Also bei mir ist es egal was ich eingebe, es wird alles hineingeschrieben.
Falls ich dich richtig verstanden habe, und du nur Zahlen, das Komma
und/oder den Punkt darstellen moechtest schau mal hier rein :
http://www.purebasic.fr/german/viewtopic.php?t=7450

Verfasst: 16.03.2008 00:23
von NicknameFJ
Also bei mir funktioniert es:

Im oberen Gadget (zum Vergleich) wird alles angenommen - normales Stringgadget

Im unteren ist die Dezimaleingabe aktiv: Nur Zahlen, Minuszeichen, und Komma/Punkt

Außerdem kann man über

InputFlags\Vorzeichen = 1
InputFlags\Nachkomma = 4
InputFlags\Vorkomma = 8

steuern, ob das Vorzeichen zulässig ist sowie die Anzahl der Vor- und Nachkommastellen.

Wußte aber nicht dass Du schon lange so was geproggt hast.

[EDIT]

@Edel:
Was hast Du für ein System, dass das Prog. nicht funzt ??

Verfasst: 16.03.2008 02:10
von Fluid Byte
Was den reinen Eingabefilter betrifft lässt sich das Ganze deutlich verkürzen. Extra Keyboard-Hooks sind unnötig:

Code: Alles auswählen

Global lpPrevFunc

Procedure EditCtrlProc(hWnd,uMsg,wParam,lParam)
	Protected BlockInput = #True
			
    If uMsg = #WM_CHAR 			
 		If wParam = #VK_SNAPSHOT And FindString(GetGadgetText(0),",",0)
 			ProcedureReturn 0   
 		ElseIf (wParam >= #VK_0 And wParam <= #VK_9) Or wParam = #VK_SNAPSHOT Or wParam = #VK_BACK
 			BlockInput = #False
 		EndIf
 		
 		If BlockInput : ProcedureReturn 0 : EndIf
    EndIf
     
    ProcedureReturn CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
EndProcedure

OpenWindow(0,0,0,320,240,"void",#PB_Window_SystemMenu | 1)
CreateGadgetList(WindowID(0))
StringGadget(0,5,5,300,25,"")

lpPrevFunc = SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@EditCtrlProc())

While WaitWindowEvent() ! #WM_CLOSE : Wend

Verfasst: 16.03.2008 14:43
von HeX0R
Gibts in der flüssigen Welt keine negativen Floats ?

Verfasst: 16.03.2008 14:57
von edel
Ich benutze Vista. Hab den Fehler aber gefunden.

Code: Alles auswählen

lpdwProcessId = GetWindowThreadProcessId_(WindowID, 0)
WindowID war nicht gueltig.

Bist du dir sicher das es bei dir funktioniert hat? ;)

Verfasst: 16.03.2008 15:14
von NicknameFJ
@Edel:

Ich habe XP Home SP3 und PB 4.10

Bei mir hat es - so wie gepostet - funktioniert :shock: . Gerade nochmal mit dem geposteten Source getestet ! Naja, egal