Les messages envoyés aux fenêtres dans une API Windows

Signaler
Messages postés
5
Date d'inscription
jeudi 7 juillet 2005
Statut
Membre
Dernière intervention
29 octobre 2008
-
Messages postés
192
Date d'inscription
vendredi 19 mars 2004
Statut
Membre
Dernière intervention
30 janvier 2008
-
Bonjour, je poste ici en espérant que ce soit le bon endroit (difficile de rechercher "message de fenêtres")...
Je programme une API en C++ sans MFC sous VS PRO 2005, et j'aimerais savoir (si il y en a un) quel est le message (du type WM_xxxx) qui est envoyé à l'appli lorsque l'on glisse la fenêtre hors de l'écran, et surtout quel est le message envoyé lorsque l'on la fait revenir sur l'écran.
en effet, le fond de ma fenêtre n'est plus réaffiché, et il ne me semble pas que WM_PAINT change quelque chose.

Merci d'avance de votre intérêt. Si vous avez besoin de plus d'infos pour me répondre, n'hésitez pas à demander.

Amicalement,
TotouiX ;)

7 réponses

Messages postés
192
Date d'inscription
vendredi 19 mars 2004
Statut
Membre
Dernière intervention
30 janvier 2008

Je ne crois pas que ce type de message existe (quelqu'un peut-il
confirmer?). Cependant en connaissant les dimensions de la fenêtre et
celle de l'écran, tu dois pouvoir coder une fonction indiquant si la
fenêtre est située hors écran ou non.
Messages postés
5
Date d'inscription
jeudi 7 juillet 2005
Statut
Membre
Dernière intervention
29 octobre 2008

Merci TheWarrior pour ta réponse rapide.
Je comprends ta solution, mais j'aimerais comprendre pourquoi je n'arrive pas à reproduire le comportement d'un fenêtre classique (une de l'OS par exemple).

Je m'explique.
J'ai 3 fenêtres (au sens 3 Hwnd). une fenêtre principale qui a deux filles (WS_CHILD). Les filles sont :
1/ un dialog avec des boutons
2/ un encart OpenGl.
Je souhaite afficher une image de fond puis par dessus mes boutons (pas des CBoutton, je n'ai pas de MFC) et à côté un petit truc en OpenGl (pas de GLUT).

J'ai donc ça :

///////////////////////////////////////
// Création de la fenêtre principale //
///////////////////////////////////////
Image_de_fond = LoadBitmapA(Hinstance, "IMAGE_FOND_ECRAN");
Hwnd_Fenetre_Principale=CreateWindow("Style_Fenetre_Principale","Espace",WS_OVERLAPPED | WS_SYSMENU | WS_EX_TRANSPARENT ,0,0,1024,768,NULL,NULL,Hinstance,NULL);

//////////////////////////////////////
// Création de la fenêtre OpenGL	//
//////////////////////////////////////
Hwnd_OpenGL=CreateWindowEx(	WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,"Style_Fenetre_OpenGL","Titre Fenêtre OpenGL",	WS_CHILD | WS_VISIBLE | WS_BORDER |	WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 416, 122, 600,	600, Hwnd_Fenetre_Principale, NULL, Hinstance, NULL);
ShowWindow(Hwnd_OpenGL,SW_SHOW);

//////////////////////////////////////
// Création du dialogue principal	//
//////////////////////////////////////
Hwnd_Dialogue_Principal=CreateDialog(Hinstance,MAKEINTRESOURCE(DIALOGUE_PRINCIPAL),Hwnd_Fenetre_Principale,(DLGPROC)Gestionnaire_des_messages_Dialogue_Principal);	
ShowWindow(Hwnd_Dialogue_Principal,SW_SHOW);

Initialisation_OpenGL();
UpdateWindow(Hwnd_Fenetre_Principale);
ShowWindow(Hwnd_Fenetre_Principale,CmdShow);



et comme je souhaite obtenir un affichage résistant au passage d'une autre fenêtre et au déplacement de ma fenêtre hors de l'écran, j'ai écrit ma fonction d'affichage entièrement dans la boucle de traitement de messages et non pas dans les gestionnaires de chaque fenêtre. (sinon, je résistais à la sortie d'écran mais pas a passage par devant de la fenêtre..)

Ce qui donne :
while (GetMessageA(&Message,NULL,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
if (		Message.message == WM_PAINT
|| Message.message == WM_NCMOUSELEAVE
// tout plein de tests sur la valeur Message.message  //
|| Message.message == WM_SHOWWINDOW
|| Message.message == 0x216
//|| Message.message == WM_TIMER
)
{

/////////////////////////
//	Et SI on peignait à partir d'ici??????
/////////////////////////
Hdc_Dialogue = BeginPaint(Hwnd_Dialogue_Principal, &ps);
DrawStateA(Hdc_Dialogue, NULL, NULL, (long)Image_de_fond, NULL, 0, 0, 0, 0, DST_BITMAP);
DessineOpenGl();
//	Et SI on peignait 2 fois le fond?
DrawStateA(Hdc_Dialogue, NULL, NULL, (long)Image_de_fond, NULL, 0, 0, 0, 0, DST_BITMAP);
EndPaint(Hwnd_Dialogue_Principal, &ps);

}
}


et là mon bidule est résistant au passage d'une fenêtre, et à la sortie d'écran SAUF l'image de fond (les boutons et l'OpenGl sont bien réaffichés).

Je m'arrache les cheveux.

Si quelqu'un voit une solution, merci d'avance.
Messages postés
192
Date d'inscription
vendredi 19 mars 2004
Statut
Membre
Dernière intervention
30 janvier 2008

Je comprends bien ton problème, je réfléchis à une solution...
As-tu essayé de réafficher le fond avant les boutons et le rendu OpenGL?
Messages postés
5
Date d'inscription
jeudi 7 juillet 2005
Statut
Membre
Dernière intervention
29 octobre 2008

Salut,
oui, en fait je ne m'occupe pas de l'affichage des boutons, l'ai l'impression qu'ils sont gérés automatiquement à partir du fichier "ressource.h" dans lequel le dialog est défini.
et comme tu peux le voir dans mon code, l'image de fond est affichée plusieurs fois :
/////////////////////////
//	Et SI on peignait à partir d'ici??????
/////////////////////////
Hdc_Dialogue = BeginPaint(Hwnd_Dialogue_Principal, &ps);
    DrawStateA(Hdc_Dialogue, NULL, NULL, (long)Image_de_fond, NULL, 0, 0, 0, 0, DST_BITMAP);
    DessineOpenGl();        // c'est ma fonction qui regroupe les instructions OpenGl!
    //	Et SI on peignait 2 fois le fond?
        DrawStateA(Hdc_Dialogue, NULL, NULL, (long)Image_de_fond, NULL, 0, 0, 0, 0, DST_BITMAP);
EndPaint(Hwnd_Dialogue_Principal, &ps);


J'affiche même l'image de fond 2 fois (une avant et une après l'OpenGl) avec la fonction DrawStateA().

Comme je ne maitrise pas complêtement les DC, je te mets le corps de ma fonction DessineOpenGl(); car j'y fais une opération sur les DC's qui pourrait peut-être chambouler le reste, en fait je ne suis pas sûr:
void DessineOpenGl()    // !!!! uniquement l'OpenGl !!!!!!    //
{
    wglMakeCurrent(Hdc_OpenGL, Hrc);    // Pour que tous les ordres opengl s'appliquent à cette fenêtre
        Efface_Fenetre_OpenGL();    // pas d'opérations sur les DC's
        Projections_OpenGL();  // pas d'opérations sur les DC's
        Eclairage_OpenGL();  // pas d'opérations sur les DC's
        Scene_OpenGL();  // pas d'opérations sur les DC's
    glFlush();
    SwapBuffers(Hdc_OpenGL);
};


à noter que je ne fais pas d'opération inverse à "wglMakeCurrent()" car celle que je connais est "wglDeleteContext(hrc)" et m'obligerait à recréer le Hdc_OpenGl à chaque itération.
"wglDeleteContext()" est tout de même appelée lorsque je quitte le programme.
J'espère ne pas t'embrouiller avec tout ça, et qu'au contraire, même, ça t'aidera.
Amicalement,
Thomas.
Messages postés
192
Date d'inscription
vendredi 19 mars 2004
Statut
Membre
Dernière intervention
30 janvier 2008

En fait ce qui me chiffone, c'est ta manière de traiter les messages windows ( dans le while GetMessage() ).

Je n'avais jamais vu cette manière de procéder du coup je me demande si ca peut marcher.

Je veux dire que tu fais une traduction du message (TranslateMessage)
puis tu le propages à ta procédure de traitement des messages par
DispatchMessage. Sauf qu'il n'y a pas de procédure de traitement des
messages! Du coup je ne suis pas sur que cela soit correct. Tu devrais
créer cette procédure et y mettre un switch( message ). Cette procédure
étant appelée en boucle, tu peut y mettre tes fonctions de
raffraichissement de la fenêtre.


Biensûr il faudrait raffraichir la fenêtre dans le cas uniquement ou il
y a superposition ou clipping de la fenêtre. Car là, c'est loin d'être
optimisé...
Messages postés
5
Date d'inscription
jeudi 7 juillet 2005
Statut
Membre
Dernière intervention
29 octobre 2008

Ouais je comprends ton désarroi.
au début je procédais comme ça, mais ça ne prenait pas.
au final, une solution qui a l'air de marcher c'est un mix entre ce que tu dis et ce que je faisais:
1/ Affichage OpenGl (uniquement l'OpenGl) là ou je l'ai expliqué. (avec les tests sur le message, on le fait si le message est WM_PAINT ou WM_NCMOUSELEAVE ou WM_NCLBUTTONUP ou WM_NCLBUTTONDOWN.)
2/ Affichage du fond dans le WM_PAINT du gestionnaire de messages du Dialogue.

Je pense pouvoir m'en sortir avec ça, merci encore pour ton aide, et à la prochaine!
Thomas.
Messages postés
192
Date d'inscription
vendredi 19 mars 2004
Statut
Membre
Dernière intervention
30 janvier 2008

Si jamais un jour tu (ou quelqu'un d'autre) trouves mieux,
postes la solution ici stp, ca doit intéresser pas mal de gens (dont
moi ).

A+