Changement d'image avec MouseMove problématique avec un Click() [Résolu/Fermé]

Signaler
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015
-
Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015
-
Bonjour,

J'avais posé une question il y a 2 jours, pas de réponses mais j'ai pu me dépatouiller tout seul. J'arrive à faire fonctionner mes boutons (qui sont des images) à peu près comme je veux (ouverture d'une application, d'un fichier ; il manque l'ouverture d'une macro).

Seulement voilà, j'ai toujours un petit problème. Voici le fichier que j'utilise pour faire mes tests de UserForm :

http://www.fichier-zip.com/2015/08/03/test-userform-outils-sd/

Le but est d'utiliser ma fonction bouton qui est dans mon module userform pour créer des boutons sans me prendre la tête, avec des images, sans avoir à rajouter de code entre temps pour faire fonctionner le bouton - mousemove, click. (et puis je suis curieux de savoir comment on peut faire un truc du genre)

Actuellement je ne sais pas si j'aurais 5,10 ou 50 boutons. X)

Bref, dans mon module de classe je gère les events mousemove et click de mes Images. Dans mon module de userform je gère le userform_mousemove.

A partir de là je veux que :
- quand je fais un mouseover sur un bouton, l'image change
- quand je fais un mouseover sur le userform (donc je quitte la zone du bouton visé précédemment), l'image rebascule sur celle d'origine

Ça ça marche, SAUF QUE, si je clique sur un bouton (avec une action associée ou non), celui-ci se retrouve bloqué avec l'image du mouseover. J'ai beau retourné sur le userform, cliquer dessus, passer sur un autre bouton ou cliquer sur un autre bouton rien n'y fait (mis à part bloquer l'image d'un autre bouton si je clique dessus :D ).


Voilà mon problème.

J'ai plein d'autres petites questions mais je pense pouvoir m'en sortir en cherchant un peu.
(liste non exhaustive si y en a qui peuvent/veulent répondre :
- visual studio community inclut-il un système de userform et d'ordre général est-ce que c'est bien ? Excel en lui-même ne me sert pas à grand-chose pour l'instant
- je trouve lourd de devoir recharger toutes mes images lorsque je fais un mouseover d'un bouton. Un moyen d'alléger ça ?
- est-ce possible d'utiliser une variable pour appeler une sub du même nom ? En fait pour ouvrir un autre fichier avec la
Private Sub Image_Click()
j'utilise la propriété Tag des images pour y mettre l'emplacement du fichier en question. Si je décide d'appeler la macro Bob, je voudrais mettre Bob dans le Tag de l'image, faire un call de mon Tag d'une certaine manière et que cela appelle bien la Sub Bob. Ou alors je dois complètement reprendre ma programmation ? :/
-Si je mets un emplacement de .exe dans le Tag d'une image, quand je clique sur le bouton l'application se lance bien mais j'ai toujours le même message : « Impossible d'ouvrir l'image dans le fichier "1" ! ». Problème avec le ShellExecute probablement mais je suis trop limité pour comprendre là. ^^")



Merci !




2 réponses

Messages postés
14987
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
17 février 2020
1 218
Bonjour,

L'anti-virus me bloque votre zip,

Pour transmettre un fichier,
il faut passer par un site de pièce jointe tel que cjoint.com

Allez sur ce site : http://cjoint.com
Clic sur parcourir,
Cherche ton fichier,
clic sur ouvrir,
Clic sur "Créer le lien cjoint",
Copier le lien,
Revenir ici le coller dans une réponse...
Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Ah désolé, je ne connais pas bien les sites d'hébergement à utiliser.
Voilà le lien : http://www.cjoint.com/c/EHeim72Gm1t

En fait j'ai réussi à faire marcher mes boutons-images. J'utilise un MouseMove pour faire un loadpicture sur une 2ème image quand je fais un mouseover et je retourne sur l'image de base avec un autre loadpicture (dans une sub reset).

Pour voir d'où pouvait venir le problème j'ai remplacer mes .loadpicture par des .backcolor et faire un test avec juste des couleurs. Résultat : quand on cliquait sur un bouton, rien ne se figeait. Donc ça vient des images.

Au final la solution : dans ma sub reset et celle de mon mousemove dans mon module de classe, je dois définir un .backcolor. Aucune idée du pourquoi du comment, mais ça marche. Et ce même si je définis dans ma fonction bouton
.BackStyle = fmBackStyleTransparent
ou
.BackStyle = fmBackStyleOpaque
. Ça reste un grand mystère pour moi mais ça marche. Manque plus que l'optimisation (moyen de faire plus simple plutôt que plein de loadpicture ?)


Je voulais savoir aussi si il était possible de différencier certaines images, d'autres images et de les récupérer de la même manière :

    Set Collect = New Collection

For Each Ctrl In Outils.Controls
    If TypeOf Ctrl Is MSForms.Image Then
        Set test3000 = New Classe1
        Set test3000.noraj = Ctrl
        Collect.Add test3000
    End If
Next Ctrl


Le but étant de continuer à récupérer mes image-bouton, mais de ne pas influer sur d'autres images (images explicatives par exemple, ou des plans incrustés en .jpg). Je voudrais rajouter un autre test pour savoir si Ctrl fait parti d'un certains groupes d'image. Aucune idée de comment faire. Peut-être avec les collection mais je ne sais pas comment ça marche. Si là j'en utilise une c'est que ce bout de code vient d'ici : http://www.commentcamarche.net/faq/10397-vba-et-les-collections-d-objets.

Merci. ^^
Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Bon bah, solution trouvée.

Vu que je gère mes image-bouton avec la propriété Tag il suffit de faire un test :
    If noraj.Tag <> "" Then
        noraj.Picture = LoadPicture("C:\SMOC\test2.jpg")
        noraj.BackColor = vbRed
    End If


Sujet clos du coup. x)
Même si le coup du .Backcolor qui débloque le LoadPicture pour un Image_Mousemove reste un mystère pour moi. °.°
Messages postés
12259
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
13 février 2020
2 332
Bonjour,

Pour te répondre au sujet du BackColor vs Picture, on ne peut qu'émettre des suppositions.
Les propriétés des contrôles d'UserForm réalisent une série d'action lorsqu'on les "alimente".
Ici, dans ce cas précis, je suppose que Microsoft a construit la propriété Picture pour n'être chargée qu'une fois (lors de l'initialize de l'userform par exemple) et ne plus être changée par la suite.
Par contre, Microsoft a du prévoir le changement de BackColor "régulier".
Pour cela, je pense (mais ne peut pas affirmer hein;-)) que la propriété BackColor n'a pas besoin d'une autre action pour être directement visible. CE n'est pas le cas de Picture.
Mais alors, me diras-tu, comment visualiser le changement de la valeur de la propriété Picture?
Tout simplement en utilisant la propriété Repaint de ton Userform.
Dans ton code, tu fais :
Me.Image1.Picture = LoadPicture("C:/MonImage.jpg")
Me.Image1.BackColor = vbRed

Si tu n'écris que :
Me.Image1.Picture = LoadPicture("C:/MonImage.jpg")
, rien ne se déclenche.
Par contre, pour ne pas avoir à modifier une autre propriété (BackColor), tu aurais pu (et devrais) faire comme ceci :
Me.Image1.Picture = LoadPicture("C:/MonImage.jpg")
Me.Repaint


Tu verras, au fur et à mesure que tu utilises les UserForm qu'il y a certaines astuces à utiliser pour visualiser certains changements de propriétés. C'est le cas ici avec la propriété Picture qui a besoin d'un Repaint pour être Ré-affichée, mais tu verras également des soucis ponctuels dans le rafraichissement de la fenêtre UserForm.
Dans certains cas, en effet (je n'ai pas d'exemple sous la main), il te faudra utiliser un DoEvents. Celui-ci va rendre la main au système d'exploitation afin que celui-ci traite les messages en attente dans ses files d'attentes, et ainsi réaliser certaines actions de rafraichissement notamment.
Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Oh ho ! Une info intéressante. En fait je me rend compte qu'il me manque plein de notions et de connaissances du VBA (VB.NET, je suppose que le problème se poserai aussi dans ce langage).

J'essaierai ça de retour de mon week-end. ^^

Merci !
pijaku
Messages postés
12259
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
13 février 2020
2 332 > Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

il me manque plein de notions et de connaissances du VBA
Je te rassure, c'est le cas de tous.
Bon week end au soleil ;-)
A++
Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Je parlais surtout de connaissances basiques. ^^

Enfin bref, j'ai fais un test rapide avec le Repaint et ça fait des flash non-stop. En fait je me sers aussi du UserForm_MouseMove pour réinitialiser les images de "bouton". Du coup dès que je suis sur le UserForm et que je bouge la souris j'ai toute la fenêtre qui s'actualise en boucle et ça donne la migraine. x)

Merci en tout cas. ^^
pijaku
Messages postés
12259
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
13 février 2020
2 332 > Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Il n'est jamais bon d'utiliser le MouseMove de l'UserForm.
Pourquoi?
Parce qu'il se déclenche en permanence lorsque tu survoles l'UserForm et donc sur une "grande surface"...
Comment faire dans ton cas?
Chaque contrôle que tu souhaites modifier doit être encapsulé dans un Frame.
De cette manière tu utilises le MouseMove de ce Frame et donc réduit la zone "d'impact".

Un dessin?
En bleu l'userform, en blanc le Frame et en rouge le contrôle.
En utilisant l'événement MouseMove du Frame, il ne se déclenche que dans la zone en blanc... Et donc sur une petite zone mais suffisante pour ton genre d'action.
A ce propos, pense à ne pas faire une zone blanche trop petite ni trop grande. 3 points devraient suffire.
Orbital38
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Je vois, merci pour l'astuce.

En fait dans mon projet j'ai cette philosophie :

Quand je survole une image que je reconnais comme un de mes "boutons" je charge image2.gif, admettons, pour l'image en question (celle en cours de mouseover).

Ensuite pour mon userform_mousemove j'appelle la même sub reset qui charge image1.gif pour tous mes boutons.

Donc là il faudra que j'associe à chaque image une frame et que je joue avec le mousemove de chaque frame et appeler ma sub reset. Ou alors plus simple (dans le fonctionnement mais pas dans le code), avec le frame_mousemove je ne charge image1.gif que pour l'image associée à la frame. Par contre là va falloir la jouer fino vu mes connaissances en VBA (entre mon module de userform, mon module de classe, et vu comme je gère mes images... bonjour, bonjour XD). Je pense que je reconnaitrais quelle frame va avec quelle image grâce au Tag. Je gère beaucoup de chose avec ça (couleur de mes boutons, savoir si je dois appeler une macro ou un fichier, savoir si c'est un Tag normal). C'est d'ailleurs comme ça que je relie un label avec une image (pour un seul bouton).

J'essaierai dans 3 jours. Ça par contre ça me serait trop utile. C'est ce genre d'astuce qui rendra mon code moins lourd (utilisation du userform_mousemove + charger les images de tous mes boutons à chaque mouseover d'un élément).

Edit : Pour alléger encore plus mon code, je pense créer 2 images plutôt qu'une seule lors de la création d'un bouton. De cette manière je jouerai plutôt sur la propriété .Visible des images plutôt que de charger mes .gif. Comme ça il n'y a qu'un seul gros chargement d'images quand j'appelle mon UserForm, mais une fois que c'est fait on ne va plus rien chercher dans le HDD (si je ne me trompe pas).