Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Fenetre TOPMOST

1 réponse
Avatar
Serge FOURNIER
Hello,

dans une app en VB6, j'utilise l'api setwindowpos pour afficher une fenetre
non modale flottante.
Lorsque je clique sur une autre app (par ex Word), la fenetre reste
flottante.
Y a t-il un moyen d'eviter cela ?

Merci

1 réponse

Avatar
Fabrice MALAINGRE
Bonjour Serge,

Si j'ai bien compris le problème, tu voudrais afficher une fenêtre «
flottante » qui reste "HWND_TOPMOST" tant que tu es dans ton application,
mais qui redevienne une fenêtre "HWND_NOTOPMOST" dès que l'utilisateur passe
sur une autre application ?

Si c'est bien le sujet de ta question, j'ai une bonne et une mauvaise
nouvelle pour toi !

D'abord la bonne : c'est effectivement possible :-)

La mauvaise c'est que ce n'est vraiment pas une sinécure :-<

Dans le principe, il faut passer ta fenêtre « flottante » en "HWND_TOPMOST"
dès que l'une des fenêtres de ton application devient active, puis la
basculer "HWND_NOTOPMOST" quand plus personne n'est actif.

Jusque là rien de très compliqué. Sauf que dans VB, les seuls messages sur
lesquels un "Form" daigne t'autoriser à réagir sont : "Form_Activate" et
"Form_Deactivate".

Et c'est là que tout ce complique : Le runtime VB filtre tellement les
messages reçus par tes fenêtres que les évènement "Form_Activate" et
"Form_Deactivate" ne sont levés que lorsque l'activation s'effectue
depuis/vers une autre fenêtre de ton application !

Je suis sûr que tu commences à prendre la mesure du problème.

A ce stade, plus qu'une seule et unique solution : tu es obligé de crocheter
les messages à destination des fenêtres de ton application !
C'est-à-dire un remplacement pur et simple de la "WindowProc" des "Form"
selon la technique dite du « Hooking » ou du « Subclasing » (de nombreux
articles sont disponibles à ce sujet sur le net.).

Une fois ta propre "WindowProc" mise en place sur chaque "Form" (grâce à un
petit appel à "SetWindowLong"), tu es en mesure d'attraper les messages de
types WM_ACTIVATE dont l'un des paramètres (octets de poids faibles de
WParam) prendra l'une des valeurs suivantes :
=> "WA_INACTIVE" : tu dois alors passer ta fenêtre « flottante » en
"HWND_NOTOPMOST".
=> "WA_ACTIVE" ou "WA_CLICKACTIVE" : tu peux basculer ta fenêtre «
flottante » en "HWND_TOPMOST".

Cela devrait donner l'effet escompté...

En espérant ne pas avoir répondu complètement à côté de la question :-)

Cordialement

____________________________
Fabrice MALAINGRE
Architecte Logiciel - Chef de Projet
THEORIS - www.theoris.fr