[R] Comment conserver des réactions de la GUI courtes ?

Aide sur les Interfaces Graphique Utilisateurs (GUI).
Règles du forum
.
Répondre
hilow
Niveau 2
Niveau 2
Messages : 28
Enregistré le : jeu. 05 avr. 2012 10:07
Localisation : 78/28
Status : Hors ligne

[R] Comment conserver des réactions de la GUI courtes ?

#1

Message par hilow »

Bonsoir,

Dans mon programme, je complète ou modifie le comportements des commandes système : minimiser, restaurer, agrandir, fermer. Seulement, lorsque le programme est occupé à un job intensif, ces fonctions associées à ces évènement système ne se déclenchent pas tout de suite. Le travail système afférent directement à Windows est lui bien effectué (minimiser minimise bien l'interface), mais l'évènement reste dans la file d'attente pour être traité au retour dans la boucle de traitement des GUIGetMsg(). Ce qui donne des comportements étranges.

Par exemple, ici, dans ce code, si Intensif() est en cours et que je clique minimiser, l'interface se minimise bien mais ne va pas en systray... Par contre, le message étant toujours dans la pile, et même si j'ai restauré la fenêtre entre temps, ça va en systray dès que Intensif() est terminé : ce qui n'a aucun sens vu de l'utilisateur.

Comment faire que Min2Tray() soit bien déclenché lorsque l'interface est minimisée, et ce en toute circonstance, même si un travail intensif est en cours ?

Code : Tout sélectionner

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ie.au3>

Opt("GuiOnEventMode", 0)
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode", 1)
Opt("TrayAutoPause", 0)
Opt("TrayIconHide", 1)

$ui = GUICreate("Responsive Min2Tray", 600, 500)
$cmd = GUICtrlCreateButton("GO", 10, 10, 75, 25)
$wb = _IECreateEmbedded()
GUICtrlCreateObj($wb, 10, 40, 580, 450)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $cmd
            GUICtrlSetState($cmd, $GUI_DISABLE)
            Intensif()
            GUICtrlSetState($cmd, $GUI_ENABLE)
        Case $GUI_EVENT_MINIMIZE
            Min2Tray()
        Case $gui_EVENT_CLOSE
            Exit(0)
    EndSwitch
WEnd

Func Intensif()
    Local $idx, $urls[2], $sel

    $urls[0] = "http://google.com"
    $urls[1]= "http://microsoft.com"

    For $idx = 0 to 50
        $sel = Mod($idx, 2)
        _IENavigate($wb, $urls[$sel], 0)
        Sleep(3000)
    Next
EndFunc

Func Min2Tray()
    GUISetState(@SW_HIDE, $ui)
    TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "Restore")
    TraySetToolTip("click to restore")
    Opt("TrayIconHide", 0)
    Return $ui
EndFunc

Func Restore()
    GUISetState(@SW_SHOW, $ui)
    WinActivate($ui)
    TraySetState(2)
    Opt("TrayIconHide", 1)
EndFunc
 
Est-ce quelque chose qui relève de la fonction AdlibRegister() ou pas ?
Modifié en dernier par hilow le ven. 20 avr. 2012 12:44, modifié 1 fois.
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2282
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Comment conserver des réactions de la GUI courtes ?

#2

Message par jchd »

Tu bloques la pompe des messages Windows en lançant un machin pareil suite à réception d'un msg particulier. Il ne faut jamais faire ça.

Passe en gestion OnEvent et surveille grâce à un ou des indicateurs globaux si tu dois interrompre ton job lourd.
Opt("GuiOnEventMode", 1)

AutoIt n'a pas une granularité extraordinaire du point de vue de la réactivité. Il reste mono-thread.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Comment conserver des réactions de la GUI courtes ?

#3

Message par mikell »

Ya aussi le GUIRegisterMsg syscommand mais je ne sais pas si la différence est significative par rapport au OnEvent

Code : Tout sélectionner

GUIRegisterMsg($WM_SYSCOMMAND, "OnSysCommand") 

Func OnSysCommand($hWnd, $Msg, $wParam, $lParam)
;SC_MINIMIZE=0xF020  ,SC_CLOSE=0xF060
    If BitAND($wParam, 0xFFF0) = 0xF020 Then  .....      
    Return 'GUI_RUNDEFMSG'
EndFunc
" 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
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2282
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Comment conserver des réactions de la GUI courtes ?

#4

Message par jchd »

Oui, c'est une autre possibilité. mais dans tous les cas, il faut absolument rendre la main dès qu'on a levé le sémaphore qui signale que telle condition est un feu vert pour l'exécution en fond de telle tâche lourde.

C'est obligatoirement ainsi qu'on conserve à l'interface une réactivité agréable pour l'usager.

Après si la tâche en question impose de recopier 100Go sur un backup, elle mettra le temps nécessaire. Pas de baguette magique dans ce pays-là. S'il faut, lancer un autre process est une très bonne alternative à une bidouille risquée où on essaye de multi-threader AutoIt (ce qui ne fonctionne pas).
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
hilow
Niveau 2
Niveau 2
Messages : 28
Enregistré le : jeu. 05 avr. 2012 10:07
Localisation : 78/28
Status : Hors ligne

Re: [..] Comment conserver des réactions de la GUI courtes ?

#5

Message par hilow »

Merci pour vos deux interventions qui m'éclairent sur la nature extreme mono-thread d'AutoIt, jchd et mikell. Je ne suis pas en mesure de faire mes tests sur l'instant, mais je vais réfléchir à tout ça... Par ailleurs, j'ai trouvé cet article dans le wiki qui me semble bien expliquer la mécanique du zinzin (sic) : http://www.autoitscript.com/wiki/Interr ... g_function

A priori, au tout départ, j'étais parti sur une gestion en MessageLoop parce que la doc indique qu'il est le mode qui permet l'interface utilisateur la plus réactive (voir la rubrique "GUI Reference"/"Gui Concepts" dans l'aide). Je cite :
"The Message-loop mode mode is best for GUIs where the GUI is "king" and all you care about is waiting for user events. [...] The OnEvent mode is best for GUIs where the GUI is of secondary importance and your script has other tasks to perform in addition to looking after the GUI."
Mes projets comportant pas mal de tâches lourdes (pas du backup mais du monitoring de séries de pages web au kilomètre, avec parsing et stockage de stats entre navigations), c'est sûr que j'ai intérêt à partir du bon pied :wink:

Bonne journée

PS : je ne passe pas en résolu tout de suite, je viendrai le faire quand ce sera le cas concrètement dans mon code 8)
Répondre