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 ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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
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
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