[R]Interdire des caractères dans une Input de GUI

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
someonescripting
Niveau 3
Niveau 3
Messages : 44
Enregistré le : mar. 16 juin 2020 03:55
Status : Hors ligne

[R]Interdire des caractères dans une Input de GUI

#1

Message par someonescripting »

Bonjour, c'est encore moi =D

J'ai besoin de votre aide pour interdire des caractères dans une InputBox. J'ai trouvé quelques exemples sur le forum et internet, mais tout cela me paraissais bien compliqué ...

Dans le cadre de mon script (toujours le même =D), j’amène l'utilisateur à potentiellement changer le nom de PC ou du WG. Je souhaiterais y faire interdire les caractères suivant : espace < > , ? ; . : / ! § ù % ^ ¨ $ £ ¤ & é ~ " # ' { ( [ | è ` \ ç ^ à @ ) ° ] = + } * µ
(Pour faire simple, je veux limiter les nom du PC et du WG de "aA" à "zZ", "0" à "9" et "-" ou "_")

Je souhaiterais que si n'importe le quel de ces caractères est saisi : soit simplement empêcher de le mettre (que l'InputBox n’interprète pas ces caractères), soit, ouvrir une MsgBox indiquant qu'un caractère interdit a été saisi. Je préfère l'option 1, mais je ne sait pas ce qu'il est possible de faire.

J'ai bien pensé à HotKeySet qui appel une fonction contenant un Sleep (1), mais cela me fait rajouter une ligne par caractère interdit, et cela ne se limite pas qu'à l'InputBox.

Voila mon script réduit au strict minimum (PoC):

Code : Tout sélectionner

#include <APIShellExConstants.au3>
#include <AutoItConstants.au3>
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <StaticConstants.au3>
#include <TabConstants.au3>
#include <WinAPIShellEx.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
#RequireAdmin ;Ce script nécessite les droits d'administrateur.

#Region ### GUI ###

;Crée la GUI et l'affiche.
Global $GUIPOW10 = GUICreate("POW10", 487, 657, 100, 104)
Global $TabSheet = GUICtrlCreateTab(8, 70, 473, 493)
Global $TabVarious = GUICtrlCreateTabItem("Paramétrages divers")
Global $CBPCName = GUICtrlCreateCheckbox("Changer le nom de l'ordinateur", 16, 102, 457, 17)
Global $InputPCName = GUICtrlCreateInput("", 35, 124, 250, 21)
GUICtrlSetState(-1, $GUI_DISABLE)
GuiCtrlSetLimit(-1,15)
GUICtrlSetTip(-1, "Saisir le nouveau nom de l'ordinateur." & @CRLF & "De ""aA"" à ""zZ"", ""0"" à ""9"", ""-"" et ""_""." & @CRLF & "Ne doit pas être composé que de chiffres.")
Global $CBWGName = GUICtrlCreateCheckbox("Changer le nom du groupe de travail.", 16, 150, 457, 17)
Global $InputWGName = GUICtrlCreateInput("", 35, 172, 250, 21)
GUICtrlSetState(-1, $GUI_DISABLE)
GuiCtrlSetLimit(-1,15)
GUICtrlSetTip(-1, "Saisir le nouveau nom du groupe de travail" & @CRLF & "De ""aA"" à ""zZ"", ""0"" à ""9"", ""-"" et ""_"".")
GUICtrlCreateTabItem("")
Global $ProgressBar = GUICtrlCreateProgress(8, 573, 471, 17)
Global $LabelStatus = GUICtrlCreateLabel ("Prêt", 8, 599, 473, 14)
Global $ButtonRestoreSystem = GUICtrlCreateButton("Point de Restauration", 8, 622, 115, 25)
Global $ButtonClose = GUICtrlCreateButton("Fermer", 325, 622, 75, 25, $BS_DEFPUSHBUTTON)
Global $ButtonApply = GUICtrlCreateButton("Appliquer", 405, 622, 75, 25)

GUISetState(@SW_SHOW)

#EndRegion ### GUI ###

#Region ### Variables ###

Global $ProgressBarStatusStart = 0 ;Valeur de départ de la ProgressBar.
Global $ProgressBarStatusMax = 60 ;Valeur MAX d'incrémentation de la ProgressBar.
Global $RebootNeeded = False ;Devient vrai si un rédémarrage est nécessaire en fonction des paramètres appliqués.
Global $RAM = Number (_WinAPI_GetPhysicallyInstalledSystemMemory()/1024/1024) ;Récupère le nombre de Go de RAM installé.
Global $CalcSWAP = Number (_WinAPI_GetPhysicallyInstalledSystemMemory()/1024*1.5) ;Calcul 1,5 fois la RAM installé afin d'être défini dans le SWAP.
Global $StopScript = False ;Devient vrai si le script doit être arrêté.

#EndRegion ### Variables ###

#Region ### Fonctions de routine ###

Func _IsChecked($idControlID) ;Renvoie vrai si la CheckBox passée en paramètre est cochée.
    Return BitAND(GUICtrlRead($idControlID), $GUI_CHECKED) = $GUI_CHECKED
EndFunc ;_IsChecked

Func _IncProgressBarStatus() ;Incrémente la ProgressBar.
	$ProgressBarStatusStart += 1
	GUICtrlSetData ($ProgressBar, $ProgressBarStatusStart/$ProgressBarStatusMax*100)
EndFunc ;_IncProgressBarStatus

#EndRegion ### Fonctions de routine ###

#Region ### Fonctions évènements ###

Func _EnableOrDisableInputPCName() ;Active ou desactive l'InputBox selon que la case "Changer le nom de l'ordinateur" est cochée ou non.
	if _IsChecked($CBPCName) Then
		GUICtrlSetState($InputPCName,$GUI_ENABLE)
	else
		GUICtrlSetState($InputPCName,$GUI_DISABLE)
	EndIf
EndFunc ;_EnableOrDisableInputPCName

Func _EnableOrDisableInputWGName() ;Active ou desactive l'InputBox selon que la case "Changer le nom du groupe de travail" est cochée ou non.
	if _IsChecked($CBWGName) Then
		GUICtrlSetState($InputWGName,$GUI_ENABLE)
	else
		GUICtrlSetState($InputWGName,$GUI_DISABLE)
	EndIf
EndFunc

Func _RestoreSystem() ;Ouvre les paramètres sytème avancés à l'onglet "Protection du système" et désactive la GUI tant que les paramètres sytème avancés ne sont pas fermés.
EndFunc ;_RestoreSystem

Func _Close() ;Affiche un message d'annulation et quitte le script.
	MsgBox (64, "Annulation", "Vous avez annulé le programme de paramétrage et d'optimisation de Windows 10" & @CRLF & "Aucun changement n'a été apporté au système")
	$StopScript = True
EndFunc ;_Close

Func _Apply() ;Désactive la GUI et applique les actions des CheckBox cochés avant d'afficher un message de fin ou une demande de redémarrage si nécessaire.
	GUISetState (@SW_DISABLE) ;Désactive la GUI.
	GUICtrlSetData ($LabelStatus, "Terminé")

	#Region ### Confirmation de fin et demande de redémarrage
	If $RebootNeeded = True Then ;Si un reboot est nécessaire, lance une demande de redémarrage.
		$RebootMsg = MsgBox (68, "Terminé", "Le paramétrage et l'optimisation de Windows 10 sont maintenant terminés." & @CRLF & "Un redémarrage est nécessaire." & @CRLF & @CRLF & _
							   "Voulez-vous redémarrer maintenant ?")
		If $RebootMsg = 6 Then ;Si on clique sur "Oui", lance le redémarrage.
			Sleep (500)
			Shutdown (6)
		EndIf
	Else ;Si le redémarrage n'est pas nécessaire, annononce la fin du programme.
		MsgBox (64, "Terminé", "Le paramétrage et l'optimisation de Windows 10 sont maintenant terminés.")
	EndIf

	$StopScript = True ;Quitte le programme en quittant la boucle.

	#EndRegion ### Confirmation de fin et demande de redémarrage
EndFunc ;_Apply
#EndRegion ### Fonctions évènements ###

#Region ### Association des évènements ###

Opt ("GUIOnEventMode", 1) ;Active le mode évènement.
GUISetOnEvent ($GUI_EVENT_CLOSE, "_Close")
GUICtrlSetOnEvent ($CBPCName, "_EnableOrDisableInputPCName")
GUICtrlSetOnEvent ($CBWGName, "_EnableOrDisableInputWGName")
GUICtrlSetOnEvent ($ButtonRestoreSystem, "_RestoreSystem")
GUICtrlSetOnEvent ($ButtonClose, "_Close")
GUICtrlSetOnEvent ($ButtonApply, "_Apply")

#EndRegion ### Association des évènement ###

While Not $StopScript
	Sleep (100)
WEnd
Suite au conseil de "TommyDDR", je suis passé en GuiOnEventMode, et c'est vrai que c'est plus propre =D
Comme d'habitude, merci d'avance pour votre aide !
Modifié en dernier par someonescripting le jeu. 02 juil. 2020 13:20, modifié 1 fois.
Un bon informaticien, est un informaticien fainéant !
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#2

Message par walkson »

Bonjour,
J'avais ce petit code que j'ai adapté à votre demande

Code : Tout sélectionner

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>

Global $regex = '(?s)[^a-z0-9A-Z-_]'
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

$gui = GUICreate("My GUI edit",220,100)
$IP = GUICtrlCreateInput("", 10, 40, 200, 22)
$lab = GUICtrlCreateLabel("", 10, 18, 200, 22)
GUISetState()

While 1
    $msg = GUIGetMsg()

    If $msg = $GUI_EVENT_CLOSE Then ExitLoop


WEnd



Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    $nNotifyCode = BitShift($wParam, 16)
    $nID = BitAND($wParam, 0x0000FFFF)
    If $nID = $IP Then
        $hCtrl = $lParam
        If $nNotifyCode = $EN_CHANGE Then
            $txt = GUICtrlRead($IP)
            $txtReplace = StringRegExpReplace($txt,$regex,"")
			If $txt <> $txtReplace Then
				GUICtrlSetBkColor($IP,0xFF0000)
			Else
				GUICtrlSetBkColor($IP,0xFFFFFF)
			EndIf

			GUICtrlSetData($lab, $txtReplace)
			GUICtrlSetData($IP, $txtReplace)
        EndIf
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc  ;==>WM_COMMAND
J'espère qu'il vous conviendra
Si vous voulez rajouter un signe, il suffit de le mettre dans la variable $regex
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#3

Message par mikell »

walkson,
[^a-z0-9A-Z-_] , c'est : [^\w-] :wink:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#4

Message par walkson »

@Michel
Comme quoi j'ai encore des choses à apprendre :D
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
someonescripting
Niveau 3
Niveau 3
Messages : 44
Enregistré le : mar. 16 juin 2020 03:55
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#5

Message par someonescripting »

Bonjour,

Merci pour vos réponses c'est juste parfait !
Maintenant j'ai pris la liberté de légèrement l'adapter à mes besoins car j'aimerais que cette commande fonctionne pour 2 Input (j'ai retiré la colorisation).

Code : Tout sélectionner

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>

Global $regex = '(?s)[^\w-]'
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

$gui = GUICreate("My GUI edit",220,100)
$InputPCName = GUICtrlCreateInput("", 10, 8, 200, 22)
$InputWGName = GUICtrlCreateInput("", 10, 40, 200, 22)
GUISetState()

While 1
    $msg = GUIGetMsg()

    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    $nNotifyCode = BitShift($wParam, 16)
    $nID = BitAND($wParam, 0x0000FFFF)
    $hCtrl = $lParam
    
    If $nID = $InputPCName Then
        If $nNotifyCode = $EN_CHANGE Then
            $txt = GUICtrlRead($InputPCName)
            $txtReplace = StringRegExpReplace($txt,$regex,"")
			GUICtrlSetData($InputPCName, $txtReplace)
        EndIf
    EndIf

    If $nID = $InputWGName Then
        If $nNotifyCode = $EN_CHANGE Then
            $txt = GUICtrlRead($InputWGName)
            $txtReplace = StringRegExpReplace($txt,$regex,"")
			GUICtrlSetData($InputWGName, $txtReplace)
        EndIf
    EndIf
    
    Return $GUI_RUNDEFMSG
EndFunc  ;==>WM_COMMAND

Maintenant quelques questions :
- Est-ce correct ou peut on assigné cette fonction à mes deux input de façon plus simple ? (ou devrais je utiliser 2 fonction distinctes (une pour chaque input) ?)
- A quoi sert "Return $GUI_RUNDEFMSG" et est il nécessaire ?
- Pour la variable "Global $regex = '(?s)[^\w-]", que représente (?s) et le ^ ?

Et dernière question mais qui n'a rien a voir avec ce cas (je n'ai pas trouvé de réponse), pourquoi met on les fonctions en bas du code ? Est-ce un choix esthétique ou pratique ?

Merci beaucoup !
Un bon informaticien, est un informaticien fainéant !
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI  

#6

Message par walkson »

Bonjour,
Pour "Return $GUI_RUNDEFMSG" je vous renvoie sur l'aide https://www.autoitscript.fr/autoit3/doc ... terMsg.htm
Pour (?s) c'est l'option "dotall" - le point matche tout (y compris les retours à la ligne) et ^ signifie exclure. Voir https://www.autoitscript.fr/autoit3/doc ... RegExp.htm
Donc je remplace (StringRegExpReplace()) par rien tout ce que je n'exclue pas. Amusez vous à supprimer le ^ pour voir le résultat (inversé).
^ peut avoir d'autres significations, Voir Ancrages et assertions dans le lien StringRegExp.htm

Pour Func WM_COMMAND($hWnd, $msg, $wParam, $lParam) on l'utilise une seule fois comme vous avez fait, idem pour les combo, les edits ou les boutons qui utilisent aussi WM_COMMAND.

Quand à la construction du code, il est logique (mais pas obligatoire) de mettre les fonctions après la GUI, d'autant plus en mode événementiel (logique de construction).
J'ai l'habitude de mettre le WM_COMMAND et autres (ex: WM_NOTIFY) en fin de code par commodité pour les retrouver.
Pour GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") certains le mettent avant la boucle et d'autres le mettent avant la GUI, moi je le préfère avant While
Modifié en dernier par walkson le jeu. 02 juil. 2020 17:00, modifié 1 fois.
Raison : rectification pour (?s)
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
someonescripting
Niveau 3
Niveau 3
Messages : 44
Enregistré le : mar. 16 juin 2020 03:55
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#7

Message par someonescripting »

C'est parfait, merci beaucoup @walkson !
Un bon informaticien, est un informaticien fainéant !
Avatar du membre
TommyDDR
Modérateur
Modérateur
Messages : 2086
Enregistré le : mar. 22 juil. 2008 21:55
Localisation : Nantes
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#8

Message par TommyDDR »

Il me semblait avoir posté mon UDF mais je ne le retrouve pas.

J'avais justement implémenté ce type d'action, je vous met un exemple, assez facilement adaptable à votre script :
#pragma compile(Icon, C:\Program Files (x86)\AutoIt3\Icons\au3.ico)
#include <GUIConstantsEx.au3>
#include "./includes/_GUICtrlEx.au3"

Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)

Global $gui
Global $input
Global $taille[2] = [300, 300]

$gui = GUICreate("", $taille[0], $taille[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "quit", $gui)
$input = GUICtrlCreateInput("", 5, 5, 290, 20)
_GUICtrlInputForceRegEx($input, "[\w-]*")
GUISetState(@SW_SHOW, $gui)

While(True)
   Sleep(10)
WEnd

Func quit()
   Exit
EndFunc
Les UDFs suivant doivent être dans un dossier nommé "includes" à coté du script principal.
Fichiers joints
_GUIRegisterMsg.au3
(2.33 Kio) Téléchargé 234 fois
_ArrayEx.au3
(20.24 Kio) Téléchargé 230 fois
_GUICtrlSetOnEvent.au3
(3.23 Kio) Téléchargé 231 fois
_GUICtrlEx.au3
(5.32 Kio) Téléchargé 241 fois
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
Avatar du membre
someonescripting
Niveau 3
Niveau 3
Messages : 44
Enregistré le : mar. 16 juin 2020 03:55
Status : Hors ligne

Re: [R]Interdire des caractères dans une Input de GUI

#9

Message par someonescripting »

Voila qui est encore plus simple !
Merci pour ton exemple @TommyDDR
Grace à toi, je n'ai eu qu'à rajouter 3 lignes dans mon code pour que cela fonctionne et j'ai même pu retirer une fonction qui existait déjà dans un de tes includes (_IsChecked).
Je te remercie également de m'avoir montré la voie du "Opt("GUIOnEventMode", 1)". =D
Juste parfait !

Je garde quand même ton exemple sous le coude @walkson.
Un bon informaticien, est un informaticien fainéant !
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Interdire des caractères dans une Input de GUI

#10

Message par mikell »

walkson a écrit : jeu. 02 juil. 2020 12:54Pour GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") certains le mettent avant la boucle et d'autres le mettent avant la GUI
Il y a une bonne raison pour vouloir mettre le(s) GUIRegisterMsg avant ou après le GuiSetState() : réduire le nombre d'appels en début d'exécution du script (pour les scripts un peu volumineux)
Le test est facile : on met un ConsoleWrite() en tête de la fonction appelée (WM_NOTIFY par exemple) et on compte les appels avant / après GuiSetState
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
someonescripting
Niveau 3
Niveau 3
Messages : 44
Enregistré le : mar. 16 juin 2020 03:55
Status : Hors ligne

Re: [R]Interdire des caractères dans une Input de GUI

#11

Message par someonescripting »

Bonjour @mikell,

N'ayant pas tout compris et ne connaissant pas encore le "ConsoleWrite()", quelle est la façon la plus optimiser de mettre le "GUIRegisterMsg" ? Avant, ou après le "GuiSetState()"
Un bon informaticien, est un informaticien fainéant !
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [R]Interdire des caractères dans une Input de GUI

#12

Message par walkson »

je viens de tester
avant la GUI, le nombre s'incrémente à 16
avant GuiSetState() le nombre s'incrémente à 10
après GuiSetState() le nombre reste à 0
ceci avec la souris hors la GUI
c'était ce que tu voulais me faire observer ?
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [R]Interdire des caractères dans une Input de GUI

#13

Message par walkson »

@someonescripting
Essayez le code
Local $cpt = 0
For $i = 1 To 20
   $cpt += $i
   ConsoleWrite($cpt & @CR)
   Sleep(500)
Next
vous allez vite comprendre
le @CR est le retour à la ligne sinon cela s'écrit sur une ligne
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R]Interdire des caractères dans une Input de GUI

#14

Message par mikell »

Si le script est peu volumineux (99% des cas) en pratique on s'en fout :mrgreen:
Sinon c'est après, voire même juste avant de lancer une action qui en aura besoin

@walkson
C'est ça. C'est beaucoup plus notable quand tu remplis une listview avec beaucoup d'items (par exemple)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
someonescripting
Niveau 3
Niveau 3
Messages : 44
Enregistré le : mar. 16 juin 2020 03:55
Status : Hors ligne

Re: [R]Interdire des caractères dans une Input de GUI

#15

Message par someonescripting »

Voilà qui m'éclaire.
Merci à vous deux !
Un bon informaticien, est un informaticien fainéant !
Répondre