StringGadget décimal (Windows) & UseMask()
Publié : lun. 08/déc./2014 2:04
Bien que récurrent, le sujet est tendance : La saisie d'un champ décimal manque à Pure Basic.
-Si vous écrivez des programmes de gestion, il est pratique de pouvoir saisir des montants décimales en précisant le nombre de décimales maximal.
Ce code n'a qu'une valeur didacticiel que je ne met pas dans la section Trucs et Astuces car mon code n'est pas vraiment une astuce ou un truc. De même je ne pense pas qu'il ne mérite pas d'être dans la section Informations et tutoriaux car il existe différentes méthodes pour arriver au même résultat et que de plus je ne lancerais pas dans des explications détaillées.
Assez blablater il est temps de parler un peu de ce code.
■ La procédure UseMask() permet d'afficher un nombre formaté suivant un masque précis (nombre de décimales, groupement des chiffres) J'utilise l'API GetNumberFormat_ (Windows) pour formater un nombre conjointement avec la structure NUMBERFMT (Windows) pour définir le masque d'affichage.
NUMBERFMT est défini dans le compilateur et vous trouverez ci-dessous quelques explications sur chacun des membres de cette structure.
-NumDigits : Nombre de chiffres à afficher après la virgule.
-LeadingZero : Si zéro, complète les chiffres après la virgule avec le nombre de zéros spécifié dans NumDigits.
-Grouping : Nombre de chiffres à inclure dans chaque groupe pour les chiffres avant la virgule. (Défaut : 3).
-lpDecimalSep : Caractère à utiliser comme séparateur décimal. (Défaut : ".").
-lpThousandSep : Caractère à utiliser comme séparateur de groupe (Défaut " ").
-NegativeOrder : Valeur représentant l'affichage d'un nombre négatif. Exemple avec le nombre -123.99 :
0 donne (123,99)
1 donne -123,99
2 donne - 123,99
3 donne 123,99-
4 donne 123,99 -
■ Plus classique, la procédure OnEventGadget() gère les différents événement sur un StringGadget()
■ Et enfin pour terminer, la procédure Open_MainForm() comme son nom l'indique, va ouvrir une fenêtre avec deux montants à saisir afin de tester le code. C'est dans cette procédure qu'on va définir une expression régulière contrôlant la saisie décimale.
■ Le codeTester la saisie classique d'un nombre, mais aussi la saisie d'un nombre négatif et regarder l'affichage quand vous quitter le champs de saisie : Exemple le nombre -123.99 donnera (123.99) les comptables adorent ce system d'affichage.
Remplacez par Tester maintenant l'arrondi des décimales : (Exemple 100.123 deviendra 100.12 Mais 100.127 deviendra 100.13)
■ A la question Est on obligé de saisir la partie décimale quand elle est égale à 0 ? La réponse est non.
Exemple : 123 affichera 123.00
-Si vous écrivez des programmes de gestion, il est pratique de pouvoir saisir des montants décimales en précisant le nombre de décimales maximal.
Ce code n'a qu'une valeur didacticiel que je ne met pas dans la section Trucs et Astuces car mon code n'est pas vraiment une astuce ou un truc. De même je ne pense pas qu'il ne mérite pas d'être dans la section Informations et tutoriaux car il existe différentes méthodes pour arriver au même résultat et que de plus je ne lancerais pas dans des explications détaillées.
Assez blablater il est temps de parler un peu de ce code.
■ La procédure UseMask() permet d'afficher un nombre formaté suivant un masque précis (nombre de décimales, groupement des chiffres) J'utilise l'API GetNumberFormat_ (Windows) pour formater un nombre conjointement avec la structure NUMBERFMT (Windows) pour définir le masque d'affichage.
NUMBERFMT est défini dans le compilateur et vous trouverez ci-dessous quelques explications sur chacun des membres de cette structure.
-NumDigits : Nombre de chiffres à afficher après la virgule.
-LeadingZero : Si zéro, complète les chiffres après la virgule avec le nombre de zéros spécifié dans NumDigits.
-Grouping : Nombre de chiffres à inclure dans chaque groupe pour les chiffres avant la virgule. (Défaut : 3).
-lpDecimalSep : Caractère à utiliser comme séparateur décimal. (Défaut : ".").
-lpThousandSep : Caractère à utiliser comme séparateur de groupe (Défaut " ").
-NegativeOrder : Valeur représentant l'affichage d'un nombre négatif. Exemple avec le nombre -123.99 :
0 donne (123,99)
1 donne -123,99
2 donne - 123,99
3 donne 123,99-
4 donne 123,99 -
■ Plus classique, la procédure OnEventGadget() gère les différents événement sur un StringGadget()
■ Et enfin pour terminer, la procédure Open_MainForm() comme son nom l'indique, va ouvrir une fenêtre avec deux montants à saisir afin de tester le code. C'est dans cette procédure qu'on va définir une expression régulière contrôlant la saisie décimale.
■ Le code
Code : Tout sélectionner
EnableExplicit
Enumeration Windows
#Mainform
EndEnumeration
Enumeration Gadgets
#Montant1
#Montant2
EndEnumeration
Enumeration RegularExpression
#Numeric
EndEnumeration
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget
Global PreviousText.s, CurrentText.s
Procedure.s UseMask(Number.s, NumDigit.l=2, LeadingZero.l=0, Grouping.l=3, lpDecimalSep.s=".", lpThousandSep.s=" ", NegativeOrder.i=0)
Protected Buffer.s, NF.NUMBERFMT
Buffer.s=Space(255)
NF\NumDigits = NumDigit
NF\LeadingZero=LeadingZero
NF\Grouping=Grouping
NF\lpDecimalSep=@lpDecimalSep
NF\lpThousandSep=@lpThousandSep
NF\NegativeOrder=NegativeOrder
GetNumberFormat_(#LOCALE_SYSTEM_DEFAULT, 0, Number, NF, @Buffer, Len(Buffer))
If StringField(Buffer, 1, ".") = ""
ProcedureReturn "0"+Buffer
Else
ProcedureReturn Buffer
EndIf
EndProcedure
Procedure OnEventGadget()
Protected Gadget = EventGadget()
Protected EndPos
Protected Buffer.s
Select EventType()
Case #PB_EventType_Focus
SetGadgetColor(Gadget, #PB_Gadget_BackColor, RGB(255, 248, 220))
PreviousText = GetGadgetText(Gadget)
Buffer = ReplaceString(PreviousText, " ","") : PreviousText = Buffer
Buffer = ReplaceString(PreviousText, "(","-") : PreviousText = Buffer
Buffer = RemoveString(PreviousText, ")") : PreviousText = Buffer
SetGadgetText(Gadget, PreviousText)
Case #PB_EventType_Change
CurrentText = GetGadgetText(Gadget)
If MatchRegularExpression(#Numeric, CurrentText) = 0
SendMessage_(GadgetID(Gadget), #EM_GETSEL, 0, @endpos)
endpos - 1
SetGadgetText(Gadget, PreviousText)
SendMessage_(GadgetID(Gadget), #EM_SETSEL, endpos, endpos)
Else
PreviousText = CurrentText
EndIf
Case #PB_EventType_LostFocus
SetGadgetText(Gadget, UseMask(PreviousText, 2))
SetGadgetColor(Gadget, #PB_Gadget_BackColor, RGB(255, 255, 255))
PreviousText = ""
EndSelect
EndProcedure
Procedure Open_MainForm()
Protected Decimal = 2 ;Nombre de décimales
CreateRegularExpression(#Numeric, "^\-{0,1}\d*$|^\-{0,1}\d+\.\d{0,"+Str(Decimal)+"}$|^$")
SetGadgetFont(#PB_Default, FontID(LoadFont(#PB_Any ,"", 11)))
OpenWindow(#Mainform, 0, 0, 500, 400, "IsNumeric", WindowStyle)
TextGadget(#PB_Any, 20, 20, 80, 20, "Montant1")
StringGadget(#Montant1, 100, 20, 100, 20, "0.00", #ES_RIGHT)
TextGadget(#PB_Any, 20, 50, 80, 20, "Montant2")
StringGadget(#Montant2, 100, 50, 100, 20, "0.00", #ES_RIGHT)
BindGadgetEvent(#Montant1, @OnEventGadget())
BindGadgetEvent(#Montant2, @OnEventGadget())
Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
EndProcedure
Open_MainForm()
Remplacez
Code : Tout sélectionner
Protected Decimal = 2 ;Nombre de décimales
Code : Tout sélectionner
Protected Decimal = 3 ;Nombre de décimales
■ A la question Est on obligé de saisir la partie décimale quand elle est égale à 0 ? La réponse est non.
Exemple : 123 affichera 123.00