Page 1 sur 2

[R] Focus ou pas de GuiCtrlCreateCombo

Posté : jeu. 06 mai 2010 16:27
par sksbir
Bonjour
j'ai découvert un comportement bizarre de guictrlcreatecombo: Quand le texte affiché est le 1er texte de la liste, le combo possède le focus, mais pas quand un autre texte de la liste est affiché.

Pour mieux comprendre, voici un script d'exemple qui est opérationnel: lancez le, puis utilisez les fleches < et > ou changez directement l'item en cliquant dans la combo. A chaque action, je détruis et recrée la fenetre ( car elle est susceptible de changer de taille ).
► Afficher le texte
Du coup, c'est assez gênant, car l'utilisation de la molette de la souris vers le bas provoque l'affiche du 2eme item de la liste de la combo, puis la fenetre perd le focus.
Mon objectif est de ne jamais avoir le focus, ou alors toujours. Bref, l'idée, c'est que toute action sur la molette de souris reste cohérente : soit ça déroule la combo d'un bout à l'autre, soit ça ne fait rien dès le départ...

. J'ai bien dans la tête une manip du genre
1/ mémoriser quelle fenetre a le focus
2/ créer ma fenetre
3/ redonner le focus à la fenetre mémorisée en 1
mais je trouve la manipulation un poil lourde pour contourner ce soucis..

Si quelqu'un a une idée :)

Re: [..] focus ou pas de guictrlcreatecombo

Posté : dim. 09 mai 2010 07:21
par SagePourpre

Code : Tout sélectionner

GUICtrlSetState($GUI_LISTE_TICKETS,$GUI_FOCUS)
Placé à la fin de ta fonction Refresh, tu donneras le focus à ton "Combo control" .
($GUI_FOCUS fonctionnera seulement si tu ajoutes #include <GUIConstantsEx.au3> )



Voilà une meilleure méthode impliquant WinGetPos et WinMove
pour produire le même résultat sans effacer ta GUI chaque fois...

Code : Tout sélectionner

#include <GUIConstantsEx.au3>
Opt('GuiOnEventMode', 1)
Local $msg
$gui = GUICreate("My GUI combo",300,300) ; will create a dialog box that when displayed is centered
GUISetOnEvent(-3,'quitter')
$combo = GUICtrlCreateCombo("item1", 10, 10) ; create first item
GUICtrlSetOnEvent(-1,'setpos')
GUICtrlSetData(-1, "item2|item3", "item1") ; add other item snd set a new default

GUISetState()

; Run the GUI until the dialog is closed
While 1
    Sleep(100)

WEnd



Func quitter()
    Exit
EndFunc   ;==>quitter


Func setpos()
    $wpos = WinGetPos($gui)
    Switch GUICtrlRead($combo)
        Case 'item1'
            WinMove($gui,'',$wpos[0],$wpos[1],300,300)
        Case 'item2'
            WinMove($gui,'',$wpos[0],$wpos[1],100,100)
        Case 'item3'
            WinMove($gui,'',$wpos[0],$wpos[1],500,200)
    EndSwitch
    GUICtrlSetState($combo,$GUI_FOCUS)
EndFunc
 
Également, à titre d'information, les fonctions devraient être déclarées à
la fin de ton script et non pas au début.

Re: [..] focus ou pas de guictrlcreatecombo

Posté : dim. 09 mai 2010 12:45
par jchd
Également, à titre d'information, les fonctions devraient être déclarées à
la fin de ton script et non pas au début.
Pour quelle raison donc ?

Re: [..] focus ou pas de guictrlcreatecombo

Posté : dim. 09 mai 2010 13:15
par SagePourpre
Par convention, tout simplement.

Ça ne change rien au niveau de l'exécution de ton script et n'affecte en
rien sa performance...

Tous les scripts ( à 99,99% ) sont construits comme cela.

Déclaration des #include
Déclaration des variables globales
Boucle principale
Déclaration des fonctions

De cette façon, n'importe qui lisant le script d'autrui s'y repère aisément.
Ça facilite l'échange inter-utilisateurs ( demandes d'aide, projets collaboratif, etc... )

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 02:38
par jchd
Mouais, c'est un peu vite oublier que dans les #include il y a ... des fonctions et souvent pas qu'une !
Pour ce qui est de la structure, on rencontre des "pascalistes" comme des tenants d'autres conventions, mais aucune ne s'impose franchement.
Du coup cette ferme incitation (le fonctions devraient être ... et non pas au début) ne devrait pas reposer sur cet argument.

Un autre argument dicte, en pratique, l'organisation d'une application de taille significative : c'est le fait qu'AutoIt soit un interpréteur "muni d'une longue-vue". Puisqu'il intreprète, le point d'exécution d'AutoIt doit être passé sur l'ensemble des déclarations globales (même celles qui ne sont pas déclarées ainsi mais qui devraient l'être) avant la première instruction non déclarative, du moins c'est le plus prudent. Je dis parfois qu'il est muni d'une longue-vue, car il n'a pas besoin d'être passé sur une fonction pour pouvoir l'invoquer : elle peut se situer au fin fond du fichier script principal, il la trouvera.

Or si l'on scinde les globales en tête et que l'on reporte les fonctions en fin, on perd la proximité des deux, ce qui est pénible dès que le script prend de l'embonpoint.
Le plus sage est de tenter d'employer la structure suivante pour des réalisations durables de taille significative :
includes standard
includes d'UDF génériques maison
includes d'UDF applicatives spécifiques
code principal (réduit si possible au minimum)

Chaque include doit rassembler les globales dont il s'occupe majoritairement. Ce n'est pas toujours possible de se passer de véritables globales, soit du fait du langage lui-même, soit pour des questions d'efficacité. Par contre, il vaut mieux tenter de s'en passer si l'on peut.

Si ces conseils ne servent pas à grand chose pour une "moulinette" de 300 lignes, ils deviennent important dans le cas de réalisations plus ambitieuses. Donc, autant prendre de bonnes habitudes dans tous les cas.

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 08:34
par Tlem
jchd a écrit :Mouais, c'est un peu vite oublier que dans les #include il y a ... des fonctions et souvent pas qu'une !
Mouais, mais un #include est une librairie dans laquelle on trouvera des variables et des fonctions. Les fonctions ne seront pas forcément toutes utilisées alors que les variables globales seront toutes déclarées. Donc, il vaut quand même mieux les placer en début de script (se qui rejoint votre explication). :wink:
jchd a écrit :Pour ce qui est de la structure, on rencontre des "pascalistes" comme des tenants d'autres conventions, mais aucune ne s'impose franchement.
Du coup cette ferme incitation (le fonctions devraient être ... et non pas au début) ne devrait pas reposer sur cet argument.
C'est pourtant la base utilisée jusqu'à présent pour tous les exemples fournit avec AutoIt (C:\Program Files\AutoIt3\Examples) !!! :roll:
Jon serait-il un Pascaliste ??? :lol:
jchd a écrit :Or si l'on scinde les globales en tête et que l'on reporte les fonctions en fin, on perd la proximité des deux, ce qui est pénible dès que le script prend de l'embonpoint.
C'est sans doute pour cela que au delà d'une certaine complexité du code, il est conseillé d'utiliser Opt('MustDeclareVars', 1) ou encore #AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6.
Mais bon, les gouts et les couleurs ...

De toutes façons, chacun est libre de faire comme il l'entend, mais d'un point de vue pratique, si les conventions du plus grand nombre sont respectées, il sera plus facile de trouver de l'aide alors qu'un script difficile à lire mettra sans aucun doute plus de temps à être assimilé. :wink:

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 14:49
par sksbir
hébé, je demande un truc, et je me trouve étiqueté "pascaliste"... :mrgreen:
Mais, c'est pas grave, j'assume :) . C'est vrai que j'ai du mal à utiliser une fonction avant de l'avoir déclarée.
Une bonne pratique c'est peut-être de mettre un gros pavé de commentaire pour indiquer où commence le "programme principal".

Code : Tout sélectionner

;****************************************************
; début du programme principal *****************************
;****************************************************
Concernant la publication d'un code pour demander de l'aide, je pense que le fait de publier un code opérationnel est déjà un préalable qui n'est pas toujours effectué.

Et concernant mon petit soucis, sagepourpre m'a apporté une réponse pleine de promesses que je vais de ce pas exploiter :) ( à suivre ... )

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 14:56
par jchd
Les exemples n'en sont pas : la plupart sont mal écrits ou illustrent des pratiques douteuses et mériteraient d'être réécrits. D'autre part, il est primordial que la partie "intressante" soit visible sur la première page écran. De plus ce n'est pas là qu'on rencontre une complexité significative. Il y a surtout un travail absolument considérable à faire sur les UDFs standard et sur l'homogénéité entre en-têtes des fonctions et texte de l'aide.
Les UDFs ne sont pas le véritable terrain de jeu de Jon ni de Jason.
C'est sans doute pour cela que au delà d'une certaine complexité du code, il est conseillé d'utiliser Opt('MustDeclareVars', 1) ou encore #AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6.
J'aurais même une forte tendance à dire que ce devrait être la règle dans tous les cas. J'ai essayé mais si on met ces directives dans une réponse à un pinpin, on part systématiquement pour 35 minutes d'explications, et ça use vite !

Comme tu dis, "l'pourceau 'l'fait à's'mode" (ti fais comme ti veux, dis).

@sksbir,
T'inquiète, c'est plutôt pas mal Pascal, Delphi, ... Je verrais ça plutôt flatteur, mis à part le côté "quiche eater" :lol:

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 15:15
par GaRydelaMer
Bonjour,

moi je fais pareil

Option AutoIt
Includes AutoIt
Includes My UDF

Var Globales
Includes Projet

While

Fonctions GUI
Fonction Events

Le tout encadré par des #Region, sous scite j'aime bien:)


Pour un de mes projets j'ai ca

Code : Tout sélectionner

#Region ;**** Options AutoIt                            ****
#Region ;**** Include AutoIt                            ****
#Region ;**** Gestion des erreurs                       ****
#Region ;**** Include My UDFs                           ****
#Region ;**** Variables                                 ****
#Region ;**** Variables des GUI                         ****
#Region ;**** Main                                      ****
#Region ;**** Création des GUI                         ****
#Region ;**** Fonctions Events                          ****
#Region ;**** Gestion de GUIMain                        ****
#Region ;**** Gestion des ListView                      ****
#Region ;**** Gestion du Menu                           ****
#Region ;**** Gestion des Boutons                       ****
#Region ;**** Fonctions Gestion du fichier XML          ****
#Region ;**** Fonctions ListView                        ****
 
Certaine région sont imbriquées.

De la même manière une bonne convention de nommage des variables et fonction et tout devient plus lisible, surtout qd on revient plus tard sur un ancien projet.

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 21:00
par Tlem
jchd a écrit :"l'pourceau 'l'fait à's'mode"
J'adore ... :lol:
C'est une expression qui vient du Canada ?

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 23:32
par jchd
C'est une richesse du Loiret, tout simplement. Vaguement dicton ou plutôt formule populaire, dont j'avoue que la fin m'échappe à ce moment précis.

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : lun. 10 mai 2010 23:40
par Tlem
à's'mode devrait pouvoir ce traduire par : a sa mode (a sa façon). :lol:

PS: On est vachement hors sujet là ... Je ferais un coup de nettoyage plus tard. ;)

Re: [..] focus ou pas de guictrlcreatecombo

Posté : mar. 18 mai 2010 16:31
par sksbir
Bien bien, revenons un peu dans le vif du sujet :
SagePourpre a écrit :

Code : Tout sélectionner

GUICtrlSetState($GUI_LISTE_TICKETS,$GUI_FOCUS)
Placé à la fin de ta fonction Refresh, tu donneras le focus à ton "Combo control" .
($GUI_FOCUS fonctionnera seulement si tu ajoutes #include <GUIConstantsEx.au3> )
Alors ceci fonctionne parfaitement, sauf que ma préférence va à ne pas donner le focus à ma dropdown. La solution a donc été de donner le focus à un autre élément de ma fenêtre, et là, c'est parfait :)

Reste tout de même la question du pourquoi de ce comportement ? Une "fonctionnalité non documentée", ou carrément un bug, l'avenir nous le dira peut-etre.
SagePourpre a écrit : Voilà une meilleure méthode impliquant WinGetPos et WinMove
pour produire le même résultat sans effacer ta GUI chaque fois... .....
Là, c'est nettement moins réussi :roll:
Il y a la remarque de la doc : WinMove has no effect on minimized windows qui est assez rédhibitoire.
En plus, j'ai un gros bug d'affichage en utilisant cette méthode (même sans iconiser ) . J'ai commenté cette partie de mon script pour le moment, et j'y reviendrai plus tard.

En tout cas, merci pour votre aide et le petit débat bien intéressant :lol:

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : mer. 19 mai 2010 00:43
par SagePourpre
Bug d'affichage ?

Le seul truc qui pourrait ressembler à ça quand j'exécute mon "script exemple", c'est la
GUI de 100x100 dont l'icône embarque légèrement sur le bouton minimiser mais ce n'est
pas du à mon script mais est le résultat de n'importe quelle GUI trop petite créée de
manière standard.

Si le "bug d'affichage" constitue autre chose, je ne pourrais pas dire puisque je n'ai rien
qui me fasse penser à un bug...


Pour ce qui est de ne pas pouvoir utiliser WinMove sur une fenêtre minimisée, en quoi est-ce un
problème puisque dans ton exemple, la GUI contrôle la position "d'elle-même" et qu'il n'est
donc pas possible d'utiliser le combo si la fenêtre est minimisée...

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : mer. 19 mai 2010 14:39
par sksbir
Hello Sagepourpre..

Puisque tu insiste pour voir ça de plus près, alors un nouveau petit script (plus ou moins) opérationnel pour te montrer ça en live :) :
► Afficher le texte
Tu choisis par exemple 2 puis 1
ensuite tu passes à 2 puis 0, et tu regardes la gueule de la fenetre... pourtant je spécifie exactement les mêmes dimensions....

Et sinon, les scripts que je publie ici sont écris spécialement pour montrer un aspect qui bugge.
Mon projet consiste à écrire un "presse-papier" avancé. En gros, à chaque fois que tu changes le presse-papier, celui-ci s'enregistre si il contient du texte : ça rajoute un item à la fenêtre (qui doit donc grandir).
Dans la partie qui boucle, il y a donc une partie de code qui scrute tout changement de contenu du presse-papier pour alimenter la fenetre, ce qui peut faire changer le contenu de celle-ci, même si elle a été iconisée.

De plus (pour la petite histoire), ce "presse-papier" avancé change en fonction d'un contexte externe.
Si contexte N°1 ( appelé ticket ), alors j'affiche tous les enregistrements de ce contexte, et quand je bascule d'un contexte à l'autre, le contenu de la fenêtre peut complètement changer.

Et je répond d'avance à la question : pourquoi écrire un truc pareil alors qu'on trouve déja plns de "advanced clipboard" et autres sur internet ? ben parce qu'après en avoir testé plusieurs, j'ai rien trouvé de bien. ça me permet également d'écrire des extensions intelligentes : par exemple, si le presse-papier contient un chemin vers un fichier ou un répertoire, ça crée un bouton "lancer" à droite dans la fenetre, à coté d'un bouton "copier"... (c'est pour ça que dans le script $GUI_LISTE_ITEM[$CPT][4] contient "4" et est à 2 dimensions...)


Mais ceci dit, je suis tout de même curieux de savoir d'où vient ce que j'appelle le "bug d'affichage"... Est-ce une erreur d'écriture de ma part , ou un vrai bug ??

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : jeu. 20 mai 2010 00:53
par SagePourpre
sksbir a écrit : Et je répond d'avance à la question : pourquoi écrire un truc pareil alors qu'on trouve déja plns de "advanced clipboard" et autres sur internet ? ...
Je comprend parfaitement la situation. Un programme tiers qui fait à peu près ce que tu souhaites
reste tout de même un programme que tu ne peux pas modifier toi-même afin d'y implémenter
tes propres améliorations.
sksbir a écrit :
Mais ceci dit, je suis tout de même curieux de savoir d'où vient ce que j'appelle le "bug d'affichage"... Est-ce une erreur d'écriture de ma part , ou un vrai bug ??
C'est une omission de ta part.

Voici un petit script simple afin de démontrer ton fameux "bug" sous un autre angle.
Redimensionne la gui et observe les contrôles.

Code : Tout sélectionner

#include <WindowsConstants.au3>
$gui = GUICreate('',400,400,-1,-1,$WS_SIZEBOX)
GUICtrlCreateCombo('',10,10,200,30)
GUICtrlCreateInput('',10,50,200,30)
GUISetState()

Sleep(10000)
 
Voici maintenant un peu de magie...

Code : Tout sélectionner

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$gui = GUICreate('',400,400,-1,-1,$WS_SIZEBOX)
GUICtrlCreateCombo('',10,10,200,30)
GUICtrlSetResizing(-1,$GUI_DOCKALL)
GUICtrlCreateInput('',10,50,200,30)
GUICtrlSetResizing(-1,$GUI_DOCKALL)
GUISetState()
Sleep(10000)
 
Il faut donc que tu assignes à chaque contrôles créé une méthode de redimensionnement.

Code : Tout sélectionner

GUICtrlSetResizing(-1,$GUI_DOCKALL) ; ou encore GUICtrlSetResizing($controle,$GUI_DOCKALL)
Cette ligne de code sert à "fixer" le contrôle dans le client et par conséquent, il restera fixe même lorsque
la GUI est redimensionnée.

En jetant un coup d'oeil à cette fonction dans l'aide, tu y verras tous les autres paramètres possibles
outre $GUI_DOCKALL.

:mrgreen:

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : jeu. 20 mai 2010 07:48
par sksbir
Bonjour sagepourpre

[mode mauvaise foi]
Mouais, encore une fonction qu'ils ont rajouté depuis la dernière release d'autoit..... :mrgreen: :mrgreen:

Plus sérieusement, merci pour ce qui commence à ressembler à un véritable cour sur les gui :)
J'ignorais jusqu'à l'existence de cette fonction, ne m'étant jamais penché sur les problématiques du redimensionnement de fenetres. Avec tes exemples, on se rend compte à quel point c'est indispensable d'avoir ce genre de fonction sous la main. Je me recolle sur mon script de ce pas... 8)

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : sam. 22 mai 2010 16:47
par SagePourpre
Merci de modifier la balise de titre [..] de votre message pour [R] si le problème
est résolu.

Re: [..] Focus ou pas de GuiCtrlCreateCombo

Posté : jeu. 22 juil. 2010 16:21
par sksbir
Houla ... le forum va bien plus vite que moi.

j'ai enfin pris le temps de tester et d'intégrer la solution, et ça marche nickel :)

donc :
- Je ne détruis plus la fenêtre , mais je me contente de la retailler avec winmove: le problème du focus soulevé initialement n'est donc plus critique. la fenêtre reste dans l'état où l'utilisateur veut l'avoir après le démarrage du programme.
- du coup, j'utilise GUICtrlSetResizing(-1,$GUI_DOCKALL) de tous les objets créés dedans, afin d'éviter que les objets en questions ne se promènent au gré des retaillage de la fenêtre.


J'ai tout de même un bémol : quand la fenetre est iconisée, la mise à jour graphique ne se fait plus : il faut donc retarder les mises à jour graphique et rafraichir la fenêtre dès qu'elle quitte son état minimisé.

Merci beaucoup et a bientôt.

Re: [R] Focus ou pas de GuiCtrlCreateCombo

Posté : jeu. 22 juil. 2010 17:53
par SagePourpre
Une version de ton code à jour afin qu'on puisse constater tout ça par nous même pourrait aider à
visualiser le problème et à possiblement trouver une solution.