Page 1 sur 2
[..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 15:35
par stevanovich
Bonjour,
Je suis confronté à un problème de méthode de programmation (il me semble) .... je vais tenter d'expliquer :
J'ai une boite de dialogue principale avec tout un tas de bouton executant des tâches windows, gérée avec une première boucle while wend .
J'ai besoin d'effectué une reconnaissance utilisateur, et pour des raisons ergonomiques, j'utilise une tierce boite de dialogue.
Cette boite de dialogue est appelée par une fonction, liée un un évènement bouton.
Donc, cette fonction affiche la boite de dialogue, et doit attendre le bon code d'authentification avant de continuer son process, pour ce, j'utilise un autre boucle while wend, ce qui semblerait poser problème ... car plus aucun évènement ne répond pendant cette seconde boucle.
code complêt :
Partiellement corrigé suite aux remarques.
► Afficher le texte
Code : Tout sélectionner
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
Opt("GUIOnEventMode", 1)
Global $b_Sortie
#Region ### START Koda GUI section ### Form=
Global $GUI_Form1 = GUICreate("Exemple while", 238, 158, 285, 167)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
Global $h_Login = GUICtrlCreateButton("Login", 32, 16, 113, 33, 0)
GUICtrlSetOnEvent($h_Login,"Process_Login")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
#Region ### START Koda GUI section ### Form=
Global $GUI_Login = GUICreate("Login", 200, 58, 348, 353)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
Global $h_Password = GUICtrlCreateInput("", 16, 8, 121, 21, BitOR($ES_PASSWORD,$ES_AUTOHSCROLL))
Global $h_Valid = GUICtrlCreateButton("OK", 144, 8, 33, 25, 0)
GUICtrlSetOnEvent($h_Valid,"Process_Valid")
#EndRegion ### END Koda GUI section ###
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func Process_Login()
MsgBox(0,"Essai","Faut taper OK",10)
ToolTip("Process_Login")
GUISetState(@SW_SHOW,$GUI_Login)
$b_Sortie = False
While 1
if $b_Sortie then
ExitLoop
EndIf
WEnd
MsgBox(0,"Essai","ok login effectué",10)
EndFunc
Func Process_Valid()
ToolTip("Process_Valid")
if GuiCtrlRead($h_Password) = "OK" Then
$b_Sortie = True
EndIf
EndFunc
Func Close()
ToolTip("Close")
MsgBox(0,"Essai","Pourqoi le Switch ne gère plus l'event close ?"&@CRLF&"Mais ceci est un autre problème ...",10)
Exit
EndFunc
Je suis preneur de toutes suggestions
Cordialement.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 15:46
par stevanovich
Oops
Je viens de penser à une solution :
Créer un .exe executant ma fonction avec un Runwait(), cependant ça oblige à sortir les password (sauf si crypter)
... et ça fait un peu bricolage ...
Cordialement
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 16:49
par GaRydelaMer
Bonjour
beaucoup d'erreur dans ton code.
1 Tu mélanges 2 concepts
Les modes évènementiels. Tu utilises mal ton 1er while avec l'option Opt("GUIOnEventMode", 1)
2 Tu as 1 variables pour 2 objets très différents: $Login
Prend pour habitude de te donner une règle de nommage des variables, et surtout de les déclarer.
$i_, pour les entiers
$GUI_, pour les Gui
$s_, pour les chaines
$h_, pour les handlers
etc.. à toi de te faire une convention pour facilement distinguer les types de variables et ainsi avoir une idée de leur contenu.
3 Utilises plutôt GuiCtrlRead() pour les contrôles créer dans ton code au lieu de ControlGetText()
4 Ta boucle While 1 dans la fonction tournera toujours, fais attention a la portée des variables, ce qui rejoint le pt 2 en les déclarant:
Dim, local, Global.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 19:00
par stevanovich
GaRydelaMer a écrit :Bonjour
beaucoup d'erreur dans ton code.
Merci pour ta réponse ...
Je n'ai pas la prétention d'être parfait , et donc j'ai envie d'apprendre
GaRydelaMer a écrit :
1 Tu mélanges 2 concepts
Les modes évènementiels. Tu utilises mal ton 1er while avec l'option Opt("GUIOnEventMode", 1)
Oui, j'avais aussi constater que cette option rendait inopérant la condition de sortie de mon 1er while ....
Et donc j'ai rajouter les event sur les GUI.
Je suis preneur de toute(s) suggestion(s) .
GaRydelaMer a écrit :
2 Tu as 1 variables pour 2 objets très différents: $Login
Prend pour habitude de te donner une règle de nommage des variables, et surtout de les déclarer.
Ok vu.
GaRydelaMer a écrit :
3 Utilises plutôt GuiCtrlRead() pour les contrôles créer dans ton code au lieu de ControlGetText()
Ok , Merci.
GaRydelaMer a écrit :
4 Ta boucle While 1 dans la fonction tournera toujours, fais attention a la portée des variables, ce qui rejoint le pt 2 en les déclarant:
Dim, local, Global.
Oui, et je souhaite qu'elle tourne toujours.
Ok pour la portée des variables.
Et concernant mon problème d'évènement plus pris en compte dès la mise en route de ma seconde boucle ?
Cordialement.
Re: [..] Deuxième Boucle while bloquant les évènem
Posté : mar. 21 sept. 2010 21:32
par stevanovich
J'ai essayé avec la fonction WinWaitClose() : Identique, plantage du script , plus aucun évènement ne répond.
► Afficher le texte
Code : Tout sélectionner
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
Global $GUI_Form1 = GUICreate("Exemple while", 238, 158, 285, 167)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
Global $h_Login = GUICtrlCreateButton("Login", 32, 16, 113, 33, 0)
GUICtrlSetOnEvent($h_Login,"Process_Login")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
#Region ### START Koda GUI section ### Form=
Global $GUI_Login = GUICreate("Login", 200, 58, 348, 353)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
Global $h_Password = GUICtrlCreateInput("", 16, 8, 121, 21, BitOR($ES_PASSWORD,$ES_AUTOHSCROLL))
Global $h_Valid = GUICtrlCreateButton("OK", 144, 8, 33, 25, 0)
GUICtrlSetOnEvent($h_Valid,"Process_Valid")
#EndRegion ### END Koda GUI section ###
While 1
;ma boucle principale
WEnd
Func Process_Login()
MsgBox(0,"Essai","Faut taper OK",10)
ToolTip("Process_Login")
GUISetState(@SW_SHOW,$GUI_Login)
WinWaitClose ( $GUI_Login ,"",10 )
MsgBox(0,"Essai","ok login effectué",10)
EndFunc
Func Process_Valid()
ToolTip("Process_Valid")
if GuiCtrlRead($h_Password) = "OK" Then
GUISetState(@SW_HIDE,$GUI_Login)
EndIf
EndFunc
Func Close()
ToolTip("Close")
MsgBox(0,"Essai","Pourqoi le Switch ne gère plus l'event close ?"&@CRLF&"Mais ceci est un autre problème ...",10)
Exit
EndFunc
Je continue mes recherches ....
Re: [..] Deuxième Boucle while bloquant les évènem
Posté : mar. 21 sept. 2010 22:26
par jbnh
Bonjour,
Merci d'utiliser le code couleur que pour les exemples de scripts et tutoriels.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 22:38
par stevanovich
jbnh a écrit :
Merci d'utiliser le code couleur que pour les exemples de scripts et tutoriels.
Bonjour,
Je m'efforce tant bien que mal à respecter la chartre, mais il semblerait qu'il y ait un bug :
1 - Mon texte apparait vert
2 - Lors de l'édition d'un post, le code repasse en =texte ???
3 - Au bout de 5 post je re re re re met en AutoIt .... jusqu'a la prochaine
Cordialement.
ReCorrigé 
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 22:44
par Jerome
Justement, on veut pas que vous mettiez le code couleur ....
Si sa s'en va, c'est qu'un modérateur le corrige a chaque fois pour l'enlever ....
Jérôme
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mar. 21 sept. 2010 22:50
par stevanovich
Jerome a écrit :Justement, on veut pas que vous mettiez le code couleur ....
Si sa s'en va, c'est qu'un modérateur le corrige a chaque fois pour l'enlever ....
Jérôme
Merci !
Expliquer comme-ça je comprends mieux
Cordialement.
Re: [..] Deuxième Boucle while bloquant les évènem
Posté : mar. 21 sept. 2010 23:11
par jbnh
Si t'enleves le winwaitclose tout marche....
Re: [..] Deuxième Boucle while bloquant les évènem
Posté : mar. 21 sept. 2010 23:37
par stevanovich
jbnh a écrit :Si t'enleves le winwaitclose tout marche....
Oui, je suis tout à fait d'accord ....
Ce que je cherchais à faire avec le WinWaitClose(), c'était d'attendre la fin du processus d'identification , donc identifié par le fermeture de la fenêtre d'identification , pour continuer mon code, un peu à l'identique d'une inputbox .
Sauf que ,elle aussi, bloque le reste du process while ... wend
Merci
jbnh.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mer. 22 sept. 2010 09:07
par stevanovich
Correction apportée pour une gestion des évènements via GUIGetMsg(1) et interruption du process en attendant la saisie du mot de passe avec une InputBox():
► Afficher le texte
Code : Tout sélectionner
;~ Opt("GUIOnEventMode", 1)
While 1
;ma boucle principale
$Msg = GUIGetMsg(1)
Select
Case $Msg[0] = $GUI_EVENT_CLOSE
Select
Case $Msg[1] = $GUI_Login
GUISetState(@SW_HIDE,$GUI_Login)
Case $Msg[1] = $GUI_Form1
GUIDelete($GUI_Form1)
Exit
EndSelect
Case $Msg[0] = $h_Login
ToolTip("$h_Login")
Func_LoginProcess1()
Case $Msg[0] = $h_Logoff
ToolTip("$h_Logoff")
Case $Msg[0] = $h_Valid
ToolTip("$h_Valid")
if GuiCtrlRead($h_Password) = "OK" Then
GUISetState(@SW_HIDE,$GUI_Login)
EndIf
EndSelect
WEnd
Func Func_LoginProcess()
Local $Password = "pppp"
while $Password <> "OK" And $Password <> ""
$Password = InputBox ( "Identification", "Entrez votre mot de passe :" , "" , "*")
WEnd
MsgBox(0,"Essai","ok login effectué")
EndFunc
L'avantage de l'InputBox(), c'est qu'elle est autogérée, le bouton OK est fonctionnel, et mon code patiente en attendant le retour de la box .....
Cependant, si l'InputBox() est affichée, la boucle While/Wend est interrompue : si le bouton logoff est actionné, rien ne se passe .
Est-ce une contrainte logicielle ? ou une erreur de programmation ?
Merci,
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : mer. 22 sept. 2010 11:54
par stevanovich
En résumé, pour contourner mon problème de blocage, je procède comme suit :
1 - Je découpe mon process en 2 parties Avant et après validation du mot de passe
2 - J'ai développé ma propre GUI de saisie de mot de passe avec passage de variable: CheckPassword($s_Password,$s_Password_True,$s_Password_False)
- Le mot de passe : $s_Password
Fonction retour sur mot de passe ok : $s_Password_True = 'PasswordTrue("Valeur")'
Fonction sur mot de passe erroné : $s_Password_False = 'PasswordFalse("Valeur")'
3 - J'utilise l'option GUIOnEventMode à 1
4 - L'évènement bouton OK de saisie du mot de passe teste la valeur de l'input, puis, selon le résultat, j'utilise la function Execute('PasswordTrue("Valeur")') avec Execute($s_Password_True) ou Execute($s_Password_False)
En espérant avoir été clair ....
Cordialement.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : sam. 25 sept. 2010 15:32
par Alexward
Salut, pour ton premier code, essai sa:
► Afficher le texte
Code : Tout sélectionner
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode",1)
Global $Form1 = GUICreate("Vérificaion de Mot de Passe", 299, 78, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
Global $Input1 = GUICtrlCreateInput("", 8, 24, 217, 21, $ES_PASSWORD)
Global $Button1 = GUICtrlCreateButton("Ok", 232, 22, 57, 25, $WS_GROUP)
GUICtrlSetOnEvent($Button1, "VerifierLeMotDePasse")
GUISetState(@SW_SHOW)
While 1
Sleep(1)
WEnd
Func Close()
Exit
EndFunc
Func VerifierLeMotDePasse()
MsgBox(0,"Le Mot de Passe", "Le Mot de Passe est: OK")
If GUICtrlRead($Input1) = "OK" Then
MsgBox(0,"Bon", "Bon Mot de passe!")
Else
MsgBox(0,"Mauvais", "Mauvais Mot de Passe")
EndIf
EndFunc
A+
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : dim. 26 sept. 2010 00:54
par stevanovich
Alexward a écrit :Salut, pour ton premier code, essai sa:
Bonjour Alexward, merci pour ta réponse.
On sort du contexte de fonctionnement que je m'étais imposé ( à tort surement).
On a une GUI avec un process en cours d'execution.
On appelle une autre GUI, déclenchée par le le bouton LOGIN , dont l'issue (Mot de passe OK) autorise ou pas la poursuite du process login .
Or ce que tu me présentes sort du cadre fonctionnel.
Bien tenté
à ce jour, je ne suis pas certain qu'il soit possible de demander à un processus d'attendre l'issue d'un résultat ou d"une boite, sans perturber les autres precess en cours.
Cordialement.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : dim. 26 sept. 2010 10:57
par Tlem
Après avoir regardé votre code (celui du premier message), voici quelques réflexions :
1 - Dans quel mode de fonctionnement voulez-vous utiliser votre script ?
Événementiel ou avec la boucle de message, car dans le code de votre premier message, il y a un mélange des deux modes. Ce qui n'aide pas vraiment le fonctionnement et la compréhension.
Si vous partez sur de l'événementiel alors vous pouvez alléger votre boucle d'attente en remplaçant tout ce qu'il y a dedans par un simple
Sleep(50).
2 - Vous créez une GUI qui est sensée être une boite de dialogue pour la GUI1. Mais en règles générale, une boite de dialogue doit être un élément enfant de sa fenêtre principale, sinon, on risque de la retrouver derrière la GUI1 !!!
3 - Ce point rejoint le point N°1, mais je doit l'expliquer afin que vous compreniez votre erreur.
Vous utilisez le mode événementiel, mais dans la fonction
Process_Login(), vous enfermez le code dans une boucle
While.
Dans ce cas précis, comment voulez-vous que votre code 'accède' au reste du script.
4 - Dans votre code, vous associez la fermeture de la GUI de vos deux fenêtres à la même fonction. Si vous ne prenez pas soin de vérifier d'où vient l'événement, alors votre programme ce terminera quelque soit la GUI que vous fermerez (y compris avec la pseudo boite de dialogue).
Si vous arrivez à résoudre ces quelques points, vous devriez pouvoir avoir un code fonctionnel.

Re: [..] Deuxième Boucle while bloquant les évènements
Posté : dim. 26 sept. 2010 14:44
par Alexward
Bon bah essaie sa

je suis sur que cela fera ton affaire
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
Global $b_Sortie
Global $Form1 = GUICreate("Exemple While", 211, 77, 192, 124)
GUISetBkColor(0x3399FF)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
Global $h_Login = GUICtrlCreateButton("Login", 32, 24, 139, 25, $WS_GROUP)
GUICtrlSetFont(-1, 10, 800, 0, "Segoe UI")
GUICtrlSetOnEvent($h_Login,"Process_Login")
GUISetState(@SW_SHOW)
Global $GUI_Login = GUICreate("Login", 185, 67, 220, 134)
GUISetBkColor(0x3399FF)
Global $h_Password = GUICtrlCreateInput("", 8, 24, 129, 21)
Global $h_Valid = GUICtrlCreateButton("Ok", 144, 22, 33, 25, $WS_GROUP)
GUICtrlSetOnEvent($h_Valid,"Process_Valid")
While 1
if $b_Sortie then ExitLoop
WEnd
Func Close()
Exit
EndFunc
Func Process_Valid()
ToolTip("Process_Valid")
if GuiCtrlRead($h_Password) = "OK" Then
$b_Sortie = True
Else
MsgBox(0,"Manqué", "Mauvais Mot de Passe")
EndIf
EndFunc
Func Process_Login()
MsgBox(0,"Essai","Faut taper OK",10)
ToolTip("Process_Login")
GUISetState(@SW_SHOW,$GUI_Login)
$b_Sortie = False
MsgBox(0,"Essai","ok login effectué",10)
EndFunc
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : dim. 26 sept. 2010 15:27
par stevanovich
Merci
Tlem d'avoir encore consacré du temps à mon code.
Tlem a écrit :Après avoir regardé votre code (celui du premier message), voici quelques réflexions :
1 - Dans quel mode de fonctionnement voulez-vous utiliser votre script ?
Événementiel ou avec la boucle de message, car dans le code de votre premier message, il y a un mélange des deux modes. Ce qui n'aide pas vraiment le fonctionnement et la compréhension.
Si vous partez sur de l'événementiel alors vous pouvez alléger votre boucle d'attente en remplaçant tout ce qu'il y a dedans par un simple Sleep(50).
Oui, c'est un copier/coller (merder) pour faire mon exemple, je travail uniquement en évènementiel.
Tlem a écrit :
2 - Vous créez une GUI qui est sensée être une boite de dialogue pour la GUI1. Mais en règles générale, une boite de dialogue doit être un élément enfant de sa fenêtre principale, sinon, on risque de la retrouver derrière la GUI1 !!!
Bien que je maîtrise bien les relations parent/child , je ne comprends pas "derrière le GUI1"
Tlem a écrit :
3 - Ce point rejoint le point N°1, mais je doit l'expliquer afin que vous compreniez votre erreur.
Vous utilisez le mode événementiel, mais dans la fonction
Process_Login(), vous enfermez le code dans une boucle
While.
Dans ce cas précis, comment voulez-vous que votre code 'accède' au reste du script.
C'est bien là que réside le problème, l'évènement n'est pas indépendant ou milti-thread, il interrompt la première boucle while en cours de fonctionnement, ce qui à mes yeux, n'est pas logique ....
Bref, bien que n'ayant pas l'habitude de gérer ce cas de figure, je pense avoir saisi cette subtilité que j'ai corrigé en découpant mon process par étapes, appelée les unes après les autres selon les évènements.
Tlem a écrit :
4 - Dans votre code, vous associez la fermeture de la GUI de vos deux fenêtres à la même fonction. Si vous ne prenez pas soin de vérifier d'où vient l'événement, alors votre programme ce terminera quelque soit la GUI que vous fermerez (y compris avec la pseudo boite de dialogue).
Oui, désolé, je n'ai pas attaché d'importance à la fermeture de mes GUI étant donné que c'était un exemple , dans le futur j'attacherai une importance particulière à expliquer ou réside le problème, en précisant que le code fourni est juste une démo.
Je reste cependant à l'écoute du point 3, car si une solution technique existe, je serai intéressé de pouvoir déclencher des évènements autonome ou multi-thread (si techniquement réalisables

)
Cordialement,
Merci.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : dim. 26 sept. 2010 15:38
par stevanovich
Alexward a écrit :Bon bah essaie sa

je suis sur que cela fera ton affaire
Bonjour Alexward ,
On approche, mais le problème reste identique, le process continue alors que le login n'est pas effectué:
On affiche "Ok login effectué" alors que ce n'est pas le cas ....
► Afficher le texte
Code : Tout sélectionner
Func Process_Login()
MsgBox(0,"Essai","Faut taper OK",10)
ToolTip("Process_Login")
GUISetState(@SW_SHOW,$GUI_Login)
$b_Sortie = False
MsgBox(0,"Essai","ok login effectué",10)
EndFunc
Comme je l'ai expliqué plus haut, la seule solution trouvée est de découpé mon process en 2 fonctions, et d"appeler la deuxième sur resultat ok en sortie du login.
D'un coté ça me permet de réutiliser ma boite login en objet dans d'autres programmation.
M'enfin bon, il n'est pas exclu que ce cas de figure se représente en programmation, ce qui m'interpelle sur la faisabilité.
Cordialement.
Re: [..] Deuxième Boucle while bloquant les évènements
Posté : dim. 26 sept. 2010 20:12
par Tlem
Je ne comprend vraiment pas votre problématique.
Lors de l'affichage de la fenêtre de login, vous n'avez rien de spécial à faire, donc pourquoi compliquer les choses ?
En ce qui concerne le 3 des messages précédents, je parlais du paramètre
parent de la commande
GUICreate.
