Page 2 sur 2

Re: Comment faire une entrée strictement décimale

Publié : lun. 08/déc./2014 17:56
par MLD
Salut a tous
Un de plus pour le fun et Window

Code : Tout sélectionner

;MLD le 4/7/2010 Entrer dans un StringGaget uniquement des chiffres , mais décimaux
Procedure String_NumericD(Gadget)   
If Len(GetGadgetText(Gadget)) <>0 
 SendMessage_(GadgetID(Gadget), #EM_GETSEL, @Debut_Position, @Fin_position)     
  a$ = Mid(GetGadgetText(Gadget),Debut_position,1)
   ValeurASCII = Asc(a$) 
    If ValeurASCII = 46
     Else
     If ValeurASCII <48 Or ValeurASCII > 57  
      y = Debut_Position
      Texte.s = GetGadgetText(Gadget)
      x = Len(Texte)
      If Mid(Texte,y,1) = "," ; modification d'une virgule en point
       Texte2.s = Left(Texte,y -1) + "." + Right(Texte,x-y)
       SetGadgetText(Gadget,Texte2)
       SendMessage_(GadgetID(Gadget), #EM_SETSEL, x + 1, x + 1) 
      Else
       Texte2.s = Left(Texte,y -1) + Right(Texte,x-y)
       SetGadgetText(Gadget,Texte2)
       SendMessage_(GadgetID(Gadget), #EM_SETSEL, x-1, x-1)    
    EndIf 
  EndIf
 EndIf 
EndIf 
EndProcedure

OpenWindow(1 , 0, 0, 300, 145,  "") 
StringGadget(2,100, 50, 90, 20, "0.00",#ES_CENTER )
SetActiveGadget(2) 
Repeat
Event = WaitWindowEvent()
 Select EventGadget()
  Case 2
  String_NumericD(2) 
 EndSelect 
Until event = #PB_Event_CloseWindow 


Re: Comment faire une entrée strictement décimale

Publié : lun. 08/déc./2014 18:14
par falsam
@MLD Bonjour. On peut saisir plusieurs point à la suite par exemple. Rien à voir avec un nombre strictement décimale.
Exemple : 0000000.......123.12 strictement décimale ?

Re: Comment faire une entrée strictement décimale

Publié : mar. 09/déc./2014 7:58
par Marc56
Voilà ma petite contribution à la cause :wink:

La méthode simple et "classique", c'est à dire laisser l'utilisateur entrer ce qu'il veut puis contrôler au travers d'une expression régulière.
- Peu de lignes
- Pas d'utilisation directe l'API
- On peut laisser l'utilisateur utiliser le point ou la virgule (on modifie ensuite au moment du calcul)
- Le contrôle se fait tout seul dès que l'utilisateur quitte le champ (s'il clique ailleurs ou passe au champ suivant par TAB). Le programme le repositionne sur le champ (effacé par défaut, mais on peut laisser)
- L'utilisateur ne pense pas que son clavier est en panne. (Combien de fois j'ai eut des appels utilisateurs "Certaines touches de mon clavier marchent plus ?" :roll: )

Code : Tout sélectionner

; Exemple de controle de saisie automatique après entrée utilisateur 
; (Controle sur perte de focus)
; Ne nécessite pas l'accès direct aux API (ex: SendMessage_ )
; Auteur: Marc56 - v1.0 - 09/12/14
; PureBasic 5.31 - www.purebasic.com


EnableExplicit

Enumeration FormWindow
  #Window_0
EndEnumeration

Enumeration FormGadget
  #Btn_Quitter
  #Str_1
  #Str_2
  #Txt_Str_1
EndEnumeration

Enumeration FormFont
  #Font_Window_0_0
  #Font_Window_0_1
EndEnumeration

LoadFont(#Font_Window_0_0,"Verdana", 10)
LoadFont(#Font_Window_0_1,"Verdana", 8)


Procedure OpenWindow_0(x = 0, y = 0, width = 600, height = 400)
  OpenWindow(#Window_0, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

  ButtonGadget(#Btn_Quitter, 465, 330, 120, 35, "&Quitter")
  SetGadgetFont(#Btn_Quitter, FontID(#Font_Window_0_0))
  StringGadget(#Str_1, 30, 45, 100, 25, "")
  SetGadgetFont(#Str_1, FontID(#Font_Window_0_0))
  StringGadget(#Str_2, 30, 85, 100, 25, "")
  SetGadgetFont(#Str_2, FontID(#Font_Window_0_0))
  TextGadget(#Txt_Str_1, 135, 50, 370, 20, "")
  SetGadgetFont(#Txt_Str_1, FontID(#Font_Window_0_1))
EndProcedure


; Masque de saisie: [négatif] 1 à 8 chiffres [point décimal] [0 à 2 décimales] 
; Adaptez selon votre souhait
Global Masque.s = "^\-?\d{1,8}\.?\d{0,2}$"
; Pour les débutants qui ne parlent pas le RegEx
; ^ 		= caractère de début de chaine
; \-? 		= signe '-' (? = 0 ou 1 seule fois) (donc facultatif) 
; \d{1,8}	= de 1 à 8 chiffres
; \.? 		= '.' décimal (0 ou 1 seule fois) (facultatif) 
; 			  on peut remplacer par [\.\,]? si on veut gérer le point ou la virgule
; \d{0,2}	= 2 chiffres (facultatif)
; $			= caractère de fin de chaine


; Le controle de saisie est fait lorsque le champ perd le focus (= si on passe au suivant ou si on clique ailleurs)
; Si la saisie est invalide, on efface le champ et on revient sur la saisie. (méthode classique de programmation)
; Important: le test ne se fait ici que pour le premier champ, le deuxième est pour la déco... adaptez-le.
Procedure Prc_CheckSTR()
	If Not CreateRegularExpression(0, Masque)
		MessageRequester("Erreur", "Le masque n'est pas bon", 48)
	Else
		Protected Chaine_1.s = GetGadgetText(#Str_1)
		If MatchRegularExpression(0, Chaine_1)	
			SetGadgetText(#Txt_Str_1, "Saisie OK")
		Else
			If GetGadgetText(#Str_1) ; Il faut vérifier que le champ est non-vide
				SetGadgetText(#Txt_Str_1, "Saisie invalide «" + Chaine_1 + "» (Ex: -123.45) ")
				SetGadgetText(#Str_1, "")
				SetActiveGadget(#Str_1)
			EndIf
		EndIf
	EndIf			
EndProcedure


OpenWindow_0()

Procedure Window_0_Events(event)
	Select event    	
	    Case #PB_Event_CloseWindow
	      	ProcedureReturn #False
	
	    Case #PB_Event_Gadget
	    	Select EventGadget()
	    		Case #Btn_Quitter
	    			ProcedureReturn #False
	    	EndSelect
	    	Select EventType()
	    		Case #PB_EventType_LostFocus
	    			Prc_CheckSTR()
	    	EndSelect 	
	    	
	EndSelect
  			ProcedureReturn #True
EndProcedure

Global event

Repeat
	event = WaitWindowEvent()
Until Window_0_Events(event) = #False

End
PS. Pour faire propre, j'aurais du mettre un FreeRegularExpression(0) à la fin de la chaine de contrôle ou mieux, faire le CreateRegularExpression() en dehors. En effet, inutile de recréer l'expression à chaque contrôle de saisie :)

Re: Comment faire une entrée strictement décimale

Publié : mar. 09/déc./2014 14:55
par MLD
@ falsam Oui avec mon code on peu saisir plusieurs points a la suite.
De même on peu saisir plusieur chiffres indentiques de suite.
Il me semble trés facile d'évité a un fou du clavier d'entré plusieur points de suite.
En fait il y a deux solutions:
1° On éradique le fou
2° une légère modification du code permet l'interdiction de plusieurs points de suite.
Personellement je préfère une troisième solution, laisser la responsabilité a la personne de ce qu'il ou elle fait en tapant sur un clavier, généralement ça rend moin bête.