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.
Tu veux dire une simple sélection multiple de cellules ? Sans édition ? Comme ci-dessous ? Étrange !
Tu peux copier la fenêtre d'exécution avec les traces ?
Voici les traces quand cela plante et que je ne peux plus fermer Excel :
SetTimerON: SetTimerOFF
SetTimerOFF: 0
SetTimerON: SetTimer 17173
TimeOutFunction: idTimer 17173
TimeOutFunction: SetTimerOFF
SetTimerOFF: 17173
UserForm_QueryClose: SetTimerOFF
SetTimerOFF: 0
plantage.gif


J'ai l'impression que c'est quand le temps d'établissement de la sélection (correspond à rester appuyé sur le bouton de la souris) est supérieure au temps de relance du timer ou alors que l'événement timer arrive pendant la sélection.
 
Dernière édition:
Excel est cruel avec les chercheurs de temps perdu.
Le fait que Application.Ready reste inchangé après que la sélection a été interrompue, je ne sais pas d'où ça vient. En tous cas il est False durant le temps où on fait une sélection.
Il a donc fallu, comme pour une cellule en édition, relancer le Timer si Not Application.Ready testé une seule fois.
 

Pièces jointes

Tout le plantage vient de cette fonction TimeOutFunction qu on doit quitter au plus vite sans exécuter aucun autre code comme la fonction Keep_TimerFunction,, toute erreur le plantage est garanti .. alors exécuter le code en asynchrone permet de sortir de la fonction TimeOutFunction avant d'appeler Keep_TimerFunction

VB:
#If VBA7 Then
    Private Sub TimeOutFunction(ByVal hWnd As LongPtr, ByVal msg As Long, ByVal idTimer As Long, ByVal dwTime As Long)
#Else
    Private Sub TimeOutFunction(ByVal hWnd As Long, ByVal msg As Long, ByVal idTimer As Long, ByVal dwTime As Long)
#End If
    Debug.Print "TimeOutFunction: idTimer " & idTimer
    Debug.Print "TimeOutFunction: SetTimerOFF"
    Call SetTimerOFF
   
    If IsCellInEdition Or (Not Application.Ready) Then
        TimerID = SetTimer(0, 0, 1000, AddressOf TimeOutFunction)
        Debug.Print "TimeOutFunction: Cell Edit or Not Ready SetTimer " & TimerID
        Exit Sub
    End If
   
   
    Application.OnTime Now, "RunAfter"
End Sub
Public Sub RunAfter()
  DoEvents
  Application.Run Keep_TimerFunction
End Sub
 
@Rheeem,
En effet, c'est une idée intéressante. D'ailleurs inutile de passer par une fonction intermédiaire, il suffit de remplacer le Run par le OnTime sur la fonction Keep_TimerFunction. Et puisque c'est async, le DoEvents n'est plus nécessaire.
 

Pièces jointes

Dernière édition:
A propos de cette "petite bidouille" (vue des sommets de l'état de l'art), si la valeur du Timer est de l'ordre de la seconde ou de plusieurs secondes, on a plutôt intérêt à passer par un Application.OnTime qui lui sait gérer nativement les situations d'attente de l'interface utilisateur et les situations de code en exécution au moment de l'échéance.

On pourrait alors dire "pas besoin de bidouille", suffit de faire un Application.OnTime et le tour est joué.
Certes, mais l'intérêt de ce code est qu'il enveloppe l'appel du Application.OnTime (Schedule True / False) sur le modèle précédent pour faire du timer résolution seconde facile en UserForm.
 

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