Page 1 sur 1
[R] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 09:13
par Zaibai
Bonjour à tous !
Le titre n'est pas forcément très explicite, voici mon (petit) problème.
Je développe une GUI avec quelques boutons/labels et je fais appel à une fonction qui les caches (hide).
Cette fonction a 3 'phases' et se déclenche via un autre bouton. (Les 3 phases sont importantes à respecter)
Mon problème est que la fonction est trop longue à s’exécuter, si on appuis deux fois sur le bouton (en ~1 secondes) la fonction ne s’exécute qu'une fois.
Pouvez-vous m'aider à optimiser ce code/cette fonction ?
Merci d'avance pour votre soutiens !
► Afficher le texte
Code : Tout sélectionner
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
_Exit()
Case $ButtonHide
ButtonHideEvent()
EndSwitch
Sleep(10)
WEnd
Func ButtonHideEvent()
If $ButtonHideEvent = 0 Then
GUICtrlSetState($ButtonSetting, $GUI_HIDE)
GUICtrlSetState($ButtonExit, $GUI_HIDE)
GUICtrlSetState($Label1, $GUI_HIDE)
$ButtonHideEvent = 1
Return
EndIf
If $ButtonHideEvent = 1 Then
GUICtrlSetState($Label2, $GUI_HIDE)
GUICtrlSetState($Label3, $GUI_HIDE)
GUICtrlSetState($Label4, $GUI_HIDE)
GUICtrlSetState($Label5, $GUI_HIDE)
$ButtonHideEvent = 2
Return
EndIf
If $ButtonHideEvent = 2 Then
GUICtrlSetState($ButtonSetting, $GUI_SHOW)
GUICtrlSetState($ButtonExit, $GUI_SHOW)
GUICtrlSetState($Label1, $GUI_SHOW)
GUICtrlSetState($Label2, $GUI_SHOW)
GUICtrlSetState($Label3, $GUI_SHOW)
GUICtrlSetState($Label4, $GUI_SHOW)
GUICtrlSetState($Label5, $GUI_SHOW)
$ButtonHideEvent = 0
Return
EndIf
EndFunc
Cordialement,
Zaibai
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 09:53
par TomAijerrie
Et en retirant le sleep(10) ?
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 09:56
par Zaibai
Bonjour,
Hélas pareil. Le problème est la fonction, pas la boucle.
Je ne vois pas comment optimiser cette fonction :/
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 10:03
par timmalos
Je ne vois pas comment optimiser votre code, qui devrait être très rapide normalement...
Déjà pour régler votre problème vous pourriez rajouter un disable avant le traitement et enable après celui ci, afin d'empecher l'utilisateur de cliquer une deuxieme fois avant la fin du premier traitement.
Code : Tout sélectionner
Case $ButtonHide
GUICtrlSetState($ButtonHide, $GUI_DISABLE)
ButtonHideEvent()
GUICtrlSetState($ButtonHide, $GUI_ENABLE)
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 14:31
par Zaibai
J'ai trouvé quel était le problème...
La fonction s’exécute bien rapidement !
En cliquant trop vite, il détecte un double clique et donc n’appuie qu'une fois sur le bouton au lieux de deux.
Le problème n'est pas très gênant, mais est-il possible de le régler ? (Via un code AutoIt bien évidement).
J'ai trouvé que ça venait de là suite à la configuration de la vitesse du double clique (via panneau de configuration).
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 14:53
par jguinch
Si le problème est résolu, merci de passer le titre du premier message en [R]
Arf, désolé, j'ai lu trop vite...
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 15:00
par timmalos
Y'a certainement moyen de capturer le DBLCLICK et d'effectuer deux fois votre fonction au lieu d'une, je regarderai un peu plus tard dans l'aprem
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 15:05
par Zaibai
@jguinch: J'ai trouvé le "réelle" problème, pas la solution.
@timmalos: Merci beaucoup, je vais aussi regarder de mon côté !
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 20:17
par Patrick22
Je vois pas bien où est le problème. J'ai repris ton code et complété la GUI pour le faire fonctionner. J'obtiens des réponses instantanées.
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
; Fenêtre GUI.
$hGUI_hW = GUICreate("Fenêtre de test", 340, 240, -1, -1)
; Labels.
$Label1 = GUICtrlCreateLabel("$Label1" , 10, 50)
$Label2 = GUICtrlCreateLabel("$Label2" , 10, 70)
$Label3 = GUICtrlCreateLabel("$Label3" , 10, 90)
$Label4 = GUICtrlCreateLabel("$Label4" , 10, 110)
$Label5 = GUICtrlCreateLabel("$Label5" , 10, 130)
; Boutons.
$ButtonHide = GUICtrlCreateButton("$ButtonHide", 25, 200, 80)
$ButtonSetting = GUICtrlCreateButton("$ButtonSetting", 125, 200, 80)
$ButtonExit = GUICtrlCreateButton("$ButtonExit", 225, 200, 80)
GUISetState()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
_Exit()
Case $ButtonHide
ButtonHideEvent()
EndSwitch
Sleep(10)
WEnd
Func ButtonHideEvent()
Static $ButtonHideEvent = 0
Static $iTimer = TimerInit()
If $ButtonHideEvent = 0 Then
GUICtrlSetState($ButtonSetting, $GUI_HIDE)
GUICtrlSetState($ButtonExit, $GUI_HIDE)
GUICtrlSetState($Label1, $GUI_HIDE)
$ButtonHideEvent = 1
ConsoleWrite("$ButtonHideEvent = 0 -> " & Round(TimerDiff($iTimer) / 1000, 2) & @CRLF)
$iTimer = TimerInit()
Return
EndIf
If $ButtonHideEvent = 1 Then
GUICtrlSetState($Label2, $GUI_HIDE)
GUICtrlSetState($Label3, $GUI_HIDE)
GUICtrlSetState($Label4, $GUI_HIDE)
GUICtrlSetState($Label5, $GUI_HIDE)
$ButtonHideEvent = 2
ConsoleWrite("$ButtonHideEvent = 1 -> " & Round(TimerDiff($iTimer) / 1000, 2) & @CRLF)
$iTimer = TimerInit()
Return
EndIf
If $ButtonHideEvent = 2 Then
GUICtrlSetState($ButtonSetting, $GUI_SHOW)
GUICtrlSetState($ButtonExit, $GUI_SHOW)
GUICtrlSetState($Label1, $GUI_SHOW)
GUICtrlSetState($Label2, $GUI_SHOW)
GUICtrlSetState($Label3, $GUI_SHOW)
GUICtrlSetState($Label4, $GUI_SHOW)
GUICtrlSetState($Label5, $GUI_SHOW)
$ButtonHideEvent = 0
ConsoleWrite("$ButtonHideEvent = 2 -> " & Round(TimerDiff($iTimer) / 1000, 2) & @CRLF)
$iTimer = TimerInit()
Return
EndIf
EndFunc
Func _Exit()
Exit
EndFunc
Voilà les durées obtenues, en secondes :
Code : Tout sélectionner
$ButtonHideEvent = 0 -> 0
$ButtonHideEvent = 1 -> 0.15
$ButtonHideEvent = 2 -> 0.13
$ButtonHideEvent = 0 -> 0.15
$ButtonHideEvent = 1 -> 0.14
$ButtonHideEvent = 2 -> 0.15
$ButtonHideEvent = 0 -> 0.15
$ButtonHideEvent = 1 -> 0.15
$ButtonHideEvent = 2 -> 0.14
$ButtonHideEvent = 0 -> 0.15
$ButtonHideEvent = 1 -> 0.14

Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 23:12
par orax
Il faudrait enlever le Sleep dans la boucle While. Il ne sert à rien avec GUIGetMsg().
Code : Tout sélectionner
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
_Exit()
Case $ButtonHide
ButtonHideEvent()
EndSwitch
WEnd
Code : Tout sélectionner
$ButtonHideEvent = 0 -> 0.02
$ButtonHideEvent = 1 -> 0.03
$ButtonHideEvent = 2 -> 0.04

Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : ven. 06 mars 2015 23:13
par jguinch
Pour intercepter le double clic, ça se passe dans WM_COMMAND.
Un petit exemple :
► Afficher le texte
Code : Tout sélectionner
#include <WindowsConstants.au3>
#Include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
GUICreate("GUI", 170, 45)
$ID_Button = GUICtrlCreateButton("click me !", 10, 10, 150, 25, $BS_NOTIFY)
GUIRegisterMsg($WM_COMMAND , "_WM_COMMAND")
GUISetState()
While 1
$msg = GUIGetMsg()
If $msg = -3 Then Exit
If $msg = $ID_Button Then ConsoleWrite("click" & @CRLF)
WEnd
Func _WM_COMMAND($hWndGUI, $MsgID, $WParam, $LParam)
Local $nNotifyCode = BitShift($WParam, 16)
Local $nID = BitAND($WParam, 0x0000FFFF)
Local $hCtrl = $LParam
Switch $nID
Case $ID_Button
Switch $nNotifyCode
Case $BN_DBLCLK
; DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hCtrl, "uint", $BM_CLICK, "wparam", 0, "lparam", 0)
ControlClick($hWndGUI, "", $hCtrl)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : lun. 09 mars 2015 10:52
par Zaibai
J'ai bien avancé sur le sujet et bonjour les bugs ?!
Le code de Patrick22, aucun problème ! (Pas besoin de détecter le double clique)
Le code de jguinch, code ok avec détection du double clique, mais en enlevant le $BS_NOTIFY de GUICtrlCreateButton, plus besoin de la détection du double clique.
En gros le $BS_NOTIFY ralentit considérablement le clique sur le bouton ?!
Suite à cette trouvaille, j'ai cherché dans mon code et "le ralentissement" est du au changement de couleur du bouton.
exemple on prend le code de Patrick22 et on change la couleur du bouton "$ButtonHide":
► Afficher le texte
Code : Tout sélectionner
#include <WindowsConstants.au3>
#Include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
; Fenêtre GUI.
$hGUI_hW = GUICreate("Fenêtre de test", 340, 240)
; Labels.
$Label1 = GUICtrlCreateLabel("$Label1" , 10, 50)
$Label2 = GUICtrlCreateLabel("$Label2" , 10, 70)
$Label3 = GUICtrlCreateLabel("$Label3" , 10, 90)
$Label4 = GUICtrlCreateLabel("$Label4" , 10, 110)
$Label5 = GUICtrlCreateLabel("$Label5" , 10, 130)
; Boutons.
$ButtonHide = GUICtrlCreateButton("$ButtonHide", 25, 200, 80, 30)
GUICtrlSetColor(-1, 0x808080)
$ButtonSetting = GUICtrlCreateButton("$ButtonSetting", 125, 200, 80)
$ButtonExit = GUICtrlCreateButton("$ButtonExit", 225, 200, 80)
GUISetState()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
_Exit()
Case $ButtonHide
ButtonHideEvent()
EndSwitch
WEnd
Func ButtonHideEvent()
Static $ButtonHideEvent = 0
Static $iTimer = TimerInit()
If $ButtonHideEvent = 0 Then
GUICtrlSetState($ButtonSetting, $GUI_HIDE)
GUICtrlSetState($ButtonExit, $GUI_HIDE)
GUICtrlSetState($Label1, $GUI_HIDE)
$ButtonHideEvent = 1
ConsoleWrite("$ButtonHideEvent = 0 -> " & Round(TimerDiff($iTimer) / 1000, 2) & @CRLF)
$iTimer = TimerInit()
Return
EndIf
If $ButtonHideEvent = 1 Then
GUICtrlSetState($Label2, $GUI_HIDE)
GUICtrlSetState($Label3, $GUI_HIDE)
GUICtrlSetState($Label4, $GUI_HIDE)
GUICtrlSetState($Label5, $GUI_HIDE)
$ButtonHideEvent = 2
ConsoleWrite("$ButtonHideEvent = 1 -> " & Round(TimerDiff($iTimer) / 1000, 2) & @CRLF)
$iTimer = TimerInit()
Return
EndIf
If $ButtonHideEvent = 2 Then
GUICtrlSetState($ButtonSetting, $GUI_SHOW)
GUICtrlSetState($ButtonExit, $GUI_SHOW)
GUICtrlSetState($Label1, $GUI_SHOW)
GUICtrlSetState($Label2, $GUI_SHOW)
GUICtrlSetState($Label3, $GUI_SHOW)
GUICtrlSetState($Label4, $GUI_SHOW)
GUICtrlSetState($Label5, $GUI_SHOW)
$ButtonHideEvent = 0
ConsoleWrite("$ButtonHideEvent = 2 -> " & Round(TimerDiff($iTimer) / 1000, 2) & @CRLF)
$iTimer = TimerInit()
Return
EndIf
EndFunc
Func _Exit()
Exit
EndFunc
Deux solutions s'offre à moi (je dois garder le changement de couleur):
- Soit je trouve une solution pour enlever ce "ralentissement" (de l'aide serait le bienvenue, pls ?)
- Soit j'utilise la détection du double clique.
Personnellement je préférerais trouvé comment enlever ce ralentissement.
PS: J'espère que mes explications sont claire. Testé le code ci-dessus pour mieux me comprendre

Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : lun. 09 mars 2015 11:51
par Oversid3
Idem je n'obtiens pas non plus de différence entre les différents step/clic.
Que doit faire ton script au final ?
Pourquoi il faut pouvoir cliquer sur ce bouton rapidement ? Tu recherche plutôt la vitesse d'exec ou un temps d'exec fixe ?
Peut-être qu'une approche différente serait à envisager pour répondre au mieux a ton besoin.
Re: [..] GUI - Fonction GUICtrlSetState (3 phases)
Posté : lun. 09 mars 2015 11:54
par mikell
Quoi que tu mettes dans le code un double clic reste un double clic
La solution de jguinch est la seule fiable
Re: [R] GUI - Fonction GUICtrlSetState (3 phases)
Posté : lun. 09 mars 2015 12:30
par Zaibai
J'aimerai juste que X clique = X Fois l’exécution de la fonction.
Avec certains paramètre, le bouton "réagis" moins vite... (voir mon message ci-dessus)
Dans ce cas là, la détection du double clique semble être obligatoire.
Si pas d'autre solution, problème résolus.
Voici le code utilisé:
► Afficher le texte
Code : Tout sélectionner
#include <WindowsConstants.au3>
#Include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
GUICreate("GUI", 170, 45)
$ID_Button = GUICtrlCreateButton("click me !", 10, 10, 150, 25, $BS_NOTIFY)
GUIRegisterMsg($WM_COMMAND , "_WM_COMMAND")
GUISetState()
While 1
$msg = GUIGetMsg()
If $msg = -3 Then Exit
If $msg = $ID_Button Then ConsoleWrite("click" & @CRLF)
WEnd
Func _WM_COMMAND($hWndGUI, $MsgID, $WParam, $LParam)
Local $nNotifyCode = BitShift($WParam, 16)
Local $nID = BitAND($WParam, 0x0000FFFF)
Local $hCtrl = $LParam
Switch $nID
Case $ID_Button
Switch $nNotifyCode
Case $BN_DBLCLK
; DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hCtrl, "uint", $BM_CLICK, "wparam", 0, "lparam", 0)
ControlClick($hWndGUI, "", $hCtrl)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Merci pour votre soutiens

Re: [R] GUI - Fonction GUICtrlSetState (3 phases)
Posté : jeu. 12 mars 2015 12:00
par Patrick22
Quoi que tu fasses, le résultat de ton code n'apparaîtra qu'après le temps nécessaire à son exécution. (Je sais c'est une évidence

)
Donc, si j'ai bien compris, ton but est de faire autant de fois l'action qu'il y a eu de clics sur le bouton.
Si c'est bien cela, et que tu travailles avec
GUIGetMsg(), le code que j'ai posté le fait. Inutile de capter un double-clic pour lequel tu n'as aucune action spécifique à exécuter. Si tu n'utilises pas
GUIRegisterMsg(), les double-clics ne seront pas interprétés comme tels.
Dans le code précédent, remplace
Code : Tout sélectionner
Func ButtonHideEvent()
Static $ButtonHideEvent = 0
Static $iTimer = TimerInit()
par
Code : Tout sélectionner
Func ButtonHideEvent()
Static $ButtonHideEvent = 0
Static $iTimer = TimerInit()
static $iNbClic = 0
$iNbClic += 1
Sleep(500)
et tous les
par
Code : Tout sélectionner
ConsoleWrite("Clic n° " & $iNbClic & " : $ButtonHideEvent = ...)
Ensuite test en comptant le nombre de clics que tu fais et tu les verras apparaître à leur heure dans la console, et avec leurs effets dans la GUI.
C'est sûr que s'il faut 0,5 s. pour exécuter un code, son effet ne pourra pas se voir avant ce délai (Je sais c'est une évidence

)
Ceci dit ton code fonctionne aussi

, je l'ai testé. Il peut cependant être source de problème parce que le code exécuté lors du clic se déroule pendant l'exécution de la fonction définie dans
GUIRegisterMsg() 
.
Il faudrait juste le modifier comme proposer à la fin de cette magnifique traduction

du
tutoriel de GUIRegisterMsg. Il y a encore d'autres façons d'exécuter ce code en dehors de
GUIRegisterMsg.
Perso, si tu travailles avec
GUIGetMsg(), je ne vois pas l'intérêt de se compliquer la vie en ajoutant une fonction pour
GUIRegisterMsg() 
mais bon, peut être que d'autres personnes y trouveront une raison valable.