XL 2016 VBA - Comment détecter la changement de position d'une fenêtre ?

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,

En gestion des évènements d'une fenêtre on a ces options:
1734412001934.png

Il n'y a pas d'évènement WindowLayout() comme il y a un évènement UserForm_Layout() et donc on ne peut pas détecter de déplacement de la Window.

Y a-t-il une parade à part faire mouliner sans fin une macro pour surveiller le layout de la Window ?
 
Dernière édition:
Solution
Et donc après une bonne dizaine d'heures de tests pour trouver la cause et la parade !!!
Ça m'a épuisé ! 😰

La cause: Après une initialisation du projet dans le VBE et uniquement dans ce cas (faut quand même le faire Excel !!!) crash Excel à cause d'un conflit entre l'évènement Application WindowResize et l'évènement SetWinEventHook EVENT_SYSTEM_MOVESIZEEND.

La parade: Désactiver les évènements Application sur l'évènement SetWinEventHook EVENT_SYSTEM_MOVESIZESTART et les réactiver sur EVENT_SYSTEM_MOVESIZEEND pour empêcher l'évènement Application WindowResize de se produire car ce dernier arrive entre les 2.
J'ai retrouvé sur un forum (!) un vieux code que j'avais fait pour tester si une cellule est en édition et intégré au mécanisme de Timer pour éviter le plantage dans ce cas.

Fichier -> voir plus loin
 
Dernière édition:
Bonjour le fil
Chez moi pas de plantage ( j'ai pas tout compris ! Lol) mais a l'ouverture du userform j'ai une boîte de dialogue qui s'ouvre je fais Ok et ça recommence ,j'ai donc fait annuler et le userform est resté affiché grisé.
Voilà
Bonne journée
Jean marie
Ps : Depuis mon téléphone
 
Hello,
moi non plus je n'ai pas de plantage avec un Excel 2021. Patricktoulon a tendance à utiliser des versions d'Excel assez anciennes alors c'est peut-être pour cela que çà a planté.
Sinon j'ai testé le timer de Dudu en éditant une cellule pendant que le Timer est actif. Cela ne plante pas mais il y a un curseur busy très actif. D'autre part si je ferme le classeur pendant le fonctionnement du Timer cela plante Excel (c'est d'ailleurs peut-être cela que patricktoulon a fait).
Ami calmant, J.P
 
Bonjour @ChTi160 & @TooFatBoy & @jurassic pork,
Merci pour vos retours.

Une solution plus simple est de relancer le timer pour 1 seconde tant qu'une cellule est en édition plutôt que boucler en DoEvents qui titillent le curseur de manière désagréable.

Pour tester, lorsque vous cliquez OK, sélectionnez rapidement une cellule et entrez quelque chose dedans. Tant que vous serez en édition de la cellule le message de relance n'apparaitra pas.
Pour fermer le UserForm, suffit de cliquer dedans.
 

Pièces jointes

Dernière édition:
Lorsqu'une cellule est en édition, il y a plusieurs options pour le Timer qui pourraient être données en paramètre:
- arrêter le Timer sans exécuter la fonction applicative liée
- forcer la sortie de l'édition par Enter ou Escape
- relancer le Timer en attendant la fin de l'édition (code actuel)
Ce qui semble sûr c'est qu'Excel n'aime pas bien avoir du code qui s'exécute lorsqu'on est en édition de cellule e.t c'est déjà pas si mal de pouvoir manipuler le Application.DisplayAlerts à ce moment là.
 
@jurassic pork,
Je n'arrive pas à repraoduire le cas où tu fermes le UserForm durant le Timer.
Dans le UserForm, le QueryClose termine le Timer, donc ça me parait bizarre.
Ou alors, il faudrait peut-être y ajouter un DoEvents ? Tu peux essayer STP ?
En fait, j'ai fait un truc plus bestial, j'ai fermé le classeur alors que j'étais en Edition de cellule et que le timer tournait
 
re
bon j'etait en train de travailler sur mon creator donc userform afffiché
j'ai ouvert ton fichier afficher ton userform et la j'etais bloqué partout

pour la peine j'ai testé avec un classeur vierge ou j'ai mi un userform je l'ai affiché (pas de code)
et là pareil
autrement dit il y a une histoire de session d'excel à prendre en compte
 
Il faut corriger la fonction TimeOutFunction pour dézinguer tous les compteurs parasites ou lorsque le module est réinstallé TimerID devient nul et le compteur sera irrécupérable ..c'est extrêmement dangereux.

VB:
Private Sub TimeOutFunction(ByVal hw As LongPtr, ByVal msg As Long, ByVal idTimer As Long, ByVal dwTime As Long)
    If TimerID <> idTimer Then
       KillTimer 0, idTimer ' compteur parasite
       Exit Sub
    End If
 
    If IsCellInEdition Then
        Exit Sub
    End If
    
    Call KillTheTimer
    Do While (Not Application.Ready)
        DoEvents
    Loop
    
    'Execute the user applicative function
    Application.Run Keep_TimerFunction
End Sub
 
Oui ça apporte une sécurité mais normalement il n'y a pas de timer parasite si le code est bien fait.

J'ai noté ceci dans le scénario de @jurassic pork:
  • Le dialogue d'enregistrement (classeur modifié), avant même un choix (Enregistrer / Ne pas enregistrer / Annuler) passe par l'Auto_Close() qui fait le Kill Timer.
  • S''il n'y a pas de dialogue (classeur non modifié), ce n'est pas le Kill Timer du UserForm_QueryClose() qui est exécuté mais le Kill Timer de l'Auto_Close() qui serait de toutes façons nécessaire si la fonction applicative sur Timer était dans un Module et pas dans un UserForm.
A vérifier s'il n'y a pas d'effets de bord.
 

Pièces jointes

- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Retour