Problème fermeture fenêtre child [Dev-cpp]

Signaler
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
-
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
-
Slut tout le monde!!

J'ai posté une question sur le forum, que j'ai en partie réussi à
résoudre... Mais il me reste un tout petit problème, le but étant
depuis une fenêtre principal, ouvrir une deuxième fenêtre depuis un
bouton.

La deuxième fenêtre s'ouvre tout à fait normalement, mais le problème
est que lorsque je la ferme, en cliquant sur la petite croix, ça ferme
tout le programme. Est ce que quelqu'un aurait la gentillesse de
m'aider??

Merci d'avance à TOUTE les réponses!!!

ps: Voici mon code:





//################################################################

#define ID_BOUTON 100

#define ID_BOUTON2 101



#include



LRESULT CALLBACK ProcedureDeFenetre (HWND,UINT,WPARAM,LPARAM); //prototype de la fonction de traitement des messages



HWND Fenetre2;

HINSTANCE hInstance2;





int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hInstancePrecedente,PSTR LigneDeCommande,int ModeAffichage)

{

char NomProgramme[ ] = "premier test";

char NomProgramme2[ ] = "deuxieme fenetre";

HWND Fenetre; //le type HWND définit un type HANDLE



HWND bouton, bouton2;

MSG Message;

WNDCLASSEX ClasseFenetre;

WNDCLASSEX DeuxFenetre;

//HINSTANCE hInstance2;



ClasseFenetre.cbSize =sizeof(ClasseFenetre);

ClasseFenetre.style = CS_HREDRAW|CS_VREDRAW;

ClasseFenetre.lpfnWndProc =ProcedureDeFenetre;

ClasseFenetre.cbClsExtra =0;

ClasseFenetre.cbWndExtra =0;

ClasseFenetre.hInstance =hInstance;

ClasseFenetre.hIcon =LoadIcon(0,IDI_APPLICATION); //LoadIcon charge un identificateur d'icone

ClasseFenetre.hCursor =LoadCursor(0,IDC_ARROW); //LoadCursor charge un identificateur de curseur

ClasseFenetre.hbrBackground =CreateSolidBrush(RGB(255,255,255)); //définit le fond d'écran de la fenêtre

ClasseFenetre.lpszMenuName =0;

ClasseFenetre.lpszClassName =NomProgramme;

ClasseFenetre.hIconSm =LoadIcon(NULL,IDI_APPLICATION);



DeuxFenetre.cbSize =sizeof(DeuxFenetre);

DeuxFenetre.style = CS_HREDRAW|CS_VREDRAW;

DeuxFenetre.lpfnWndProc =ProcedureDeFenetre;

DeuxFenetre.cbClsExtra =0;

DeuxFenetre.cbWndExtra =0;

DeuxFenetre.hInstance =hInstance;

DeuxFenetre.hIcon =LoadIcon(0,IDI_APPLICATION); //LoadIcon charge un identificateur d'icone

DeuxFenetre.hCursor =LoadCursor(0,IDC_ARROW); //LoadCursor charge un identificateur de curseur

DeuxFenetre.hbrBackground =CreateSolidBrush(RGB(255,0,0)); //définit le fond d'écran de la fenêtre

DeuxFenetre.lpszMenuName =0;

DeuxFenetre.lpszClassName =NomProgramme2;

DeuxFenetre.hIconSm =LoadIcon(NULL,IDI_APPLICATION);



RegisterClassEx(&ClasseFenetre); //on enregistre la classe de la fenêtre

RegisterClassEx(&DeuxFenetre); //on enregistre la classe de la fenêtre



//CreateWindow va créer "visuellement" une fenetre qui utilisera la classe enregistree

Fenetre=CreateWindow(NomProgramme, //nom de la classe de fenetre


"premier programme", //titre de la fenêtre visible


WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, //style de la
fenetre


GetSystemMetrics(SM_CXSCREEN)/3, //emplacement x à l'appel


GetSystemMetrics(SM_CYSCREEN)/3, //emplacement y à l'appel


200, //taille sur l'axe x


200, //taille sur l'axe y


NULL,


NULL, //handle du menu


hInstance, //handle de l'instance (instance déclarée en haut)


NULL); //paramètres supplementaires



bouton = CreateWindowEx(0,

"BUTTON",


"salut",

WS_VISIBLE|WS_CHILD,


10,


10,


100,


35,

Fenetre,

(HMENU)ID_BOUTON,

hInstance,

NULL);



Fenetre2=CreateWindow(NomProgramme2, //nom de la classe de fenetre


"deuxieme fenetre", //titre de la fenêtre visible


WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, //style de la fenetre


(GetSystemMetrics(SM_CXSCREEN)/3)+50, //emplacement x à l'appel


(GetSystemMetrics(SM_CYSCREEN)/3)+50, //emplacement y à l'appel


200, //taille sur l'axe x


200, //taille sur l'axe y


NULL,


NULL, //handle du menu


hInstance, //handle de l'instance (instance déclarée en haut)


NULL); //paramètres supplementaires








ShowWindow(Fenetre,ModeAffichage);//afficher la fenêtre à l'écran

UpdateWindow(Fenetre);//mise à jour de la fenêtre



//Lecture d'un message dans la file d'attente

while(GetMessage(&Message,NULL,0,0))

{

TranslateMessage(&Message);

DispatchMessage(&Message);

}

return Message.wParam;

}





LRESULT CALLBACK ProcedureDeFenetre(HWND fen,UINT msg,WPARAM wparam,LPARAM lparam)

{

switch(msg)

{



case WM_COMMAND:



// Vérifie que c'est bien le bouton Vérifie si on à cliquer sur le bouton

if ((LOWORD(wparam) ID_BOUTON) && (HIWORD(wparam) BN_CLICKED))

{

ShowWindow(Fenetre2,SW_SHOW);//afficher la fenêtre à l'écran

UpdateWindow(Fenetre2);//mise à jour de la fenêtre

}



break;



case WM_DESTROY:

PostQuitMessage(0);//arret du programme

return 0;

}

return DefWindowProc(fen,msg,wparam,lparam);

}

//################################################################

10 réponses

Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
Pour commencer tu enregistres deux classes identiques, ca ne sert a
rien, autant n'en utiliser qu'une seule. Quand tu fermes une fenêtre,
tu appelles PostQuitMessage(0); c'est pour ca que ton programme se
termine (n'utilise PostQuitMessage que pour la fenêtre principale)
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
1
Merci de ta réponse si rapide!

Mais qu'est ce que je devrais mettre de différent dans la deuxième
classe? Et qu'est ce que je devrais mettre dans la fonction
postquitmessage?

Merci! by_rabbit_08
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
en général c'est surtout la WndProc qui est différente. Dans la deuxième tu ne gère pas le message WM_DESTROY
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
1
Tu n'aurais pas un petit exemple vite fait? parce que je suis un vrai de vrai débutant...

Comment fais tu pour déclarer une autre procédure de fenêtre (je peux
dire comme ca je crois), est-ce que je dois faire un autre WM_DESTROY?

Merci d'avance
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
ProcedureDeFenetre est un procédure, tu en crée une autre identique que
tu appelles ProcedureDeFenetre2 par exemple, et dans celle la tu
enleves case WM_DESTROY et ce qui suit.

Si tu es débutant la dedans, je te conseille de lire le livre de petzold que tu trouves ici:

http://brunews.free.fr/brunews/index.htm
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
1
Merci pour le conseil, mais juste une dernière question (enfin je pense ),

Est-ce que je dois redéclarer entièrement la fonction du type:

LRESULT CALLBACK ProcedureDeFenetre (HWND,UINT,WPARAM,LPARAM);.

?

Et est-ce que je laisserais toujours 0 dans postquitmessage?

merci bcp de m'accorder du temps...
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
Oui tu redéclares, par contre dans le 2ème tu n'appelles plus
PostQuitMessage (tu enleve cette ligne qui provoque la fin du
programme):

http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/postquitmessage.asp
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
1
MERCI!! J'ai enfin réussi!!!!! je suis un homme heureux!!! lol

Mais il me reste un dernier problème, lorsque j'ouvre la deuxième
fenêtre, et que je la ferme, ça joue, mais si je veux la réouvrir en
cliquant à nouveau sur le bouton, ça ne marche pas !!!! Est-ce que tu saurais pourquoi??

Voici mon code:



//###################################################



#define ID_BOUTON 100

#define ID_BOUTON2 101



#include



LRESULT CALLBACK ProcedureDeFenetre (HWND,UINT,WPARAM,LPARAM); //prototype de la fonction de traitement des messages

LRESULT CALLBACK ProcedureDeFenetre2 (HWND,UINT,WPARAM,LPARAM); //prototype de la fonction de traitement des messages





HWND Fenetre2;

HINSTANCE hInstance2;





int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hInstancePrecedente,PSTR LigneDeCommande,int ModeAffichage)

{

char NomProgramme[ ] = "premier test";

char NomProgramme2[ ] = "deuxieme fenetre";

HWND Fenetre; //le type HWND définit un type HANDLE



HWND bouton, bouton2;

MSG Message;

WNDCLASSEX ClasseFenetre;

WNDCLASSEX DeuxFenetre;

//HINSTANCE hInstance2;



ClasseFenetre.cbSize =sizeof(ClasseFenetre);

ClasseFenetre.style = CS_HREDRAW|CS_VREDRAW;

ClasseFenetre.lpfnWndProc =ProcedureDeFenetre;

ClasseFenetre.cbClsExtra =0;

ClasseFenetre.cbWndExtra =0;

ClasseFenetre.hInstance =hInstance;

ClasseFenetre.hIcon =LoadIcon(0,IDI_APPLICATION); //LoadIcon charge un identificateur d'icone

ClasseFenetre.hCursor =LoadCursor(0,IDC_ARROW); //LoadCursor charge un identificateur de curseur

ClasseFenetre.hbrBackground =CreateSolidBrush(RGB(255,255,255)); //définit le fond d'écran de la fenêtre

ClasseFenetre.lpszMenuName =0;

ClasseFenetre.lpszClassName =NomProgramme;

ClasseFenetre.hIconSm =LoadIcon(NULL,IDI_APPLICATION);



DeuxFenetre.cbSize =sizeof(DeuxFenetre);

DeuxFenetre.style = CS_HREDRAW|CS_VREDRAW;

DeuxFenetre.lpfnWndProc =ProcedureDeFenetre2;

DeuxFenetre.cbClsExtra =0;

DeuxFenetre.cbWndExtra =0;

DeuxFenetre.hInstance =hInstance;

DeuxFenetre.hIcon =LoadIcon(0,IDI_APPLICATION); //LoadIcon charge un identificateur d'icone

DeuxFenetre.hCursor =LoadCursor(0,IDC_ARROW); //LoadCursor charge un identificateur de curseur

DeuxFenetre.hbrBackground =CreateSolidBrush(RGB(255,0,0)); //définit le fond d'écran de la fenêtre

DeuxFenetre.lpszMenuName =0;

DeuxFenetre.lpszClassName =NomProgramme2;

DeuxFenetre.hIconSm =LoadIcon(NULL,IDI_APPLICATION);



RegisterClassEx(&ClasseFenetre); //on enregistre la classe de la fenêtre

RegisterClassEx(&DeuxFenetre); //on enregistre la classe de la fenêtre



//CreateWindow va créer "visuellement" une fenetre qui utilisera la classe enregistree

Fenetre=CreateWindow(NomProgramme, //nom de la classe de fenetre


"premier programme", //titre de la fenêtre visible


WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, //style de la
fenetre


GetSystemMetrics(SM_CXSCREEN)/3, //emplacement x à l'appel


GetSystemMetrics(SM_CYSCREEN)/3, //emplacement y à l'appel


200, //taille sur l'axe x


200, //taille sur l'axe y


NULL,


NULL, //handle du menu


hInstance, //handle de l'instance (instance déclarée en haut)


NULL); //paramètres supplementaires



bouton = CreateWindowEx(0,

"BUTTON",


"salut",

WS_VISIBLE|WS_CHILD,


10,


10,


100,


35,

Fenetre,

(HMENU)ID_BOUTON,

hInstance,

NULL);



Fenetre2=CreateWindow(NomProgramme2, //nom de la classe de fenetre


"deuxieme fenetre", //titre de la fenêtre visible


WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, //style de la fenetre


(GetSystemMetrics(SM_CXSCREEN)/3)+50, //emplacement x à l'appel


(GetSystemMetrics(SM_CYSCREEN)/3)+50, //emplacement y à l'appel


200, //taille sur l'axe x


200, //taille sur l'axe y


NULL,


NULL, //handle du menu


hInstance, //handle de l'instance (instance déclarée en haut)


NULL); //paramètres supplementaires








ShowWindow(Fenetre,ModeAffichage);//afficher la fenêtre à l'écran

UpdateWindow(Fenetre);//mise à jour de la fenêtre



//Lecture d'un message dans la file d'attente

while(GetMessage(&Message,NULL,0,0))

{

TranslateMessage(&Message);

DispatchMessage(&Message);

}

return Message.wParam;

}





LRESULT CALLBACK ProcedureDeFenetre(HWND fen,UINT msg,WPARAM wparam,LPARAM lparam)

{

switch(msg)

{



case WM_COMMAND:



// Vérifie que c'est bien le bouton Vérifie si on à cliquer sur le bouton

if ((LOWORD(wparam) ID_BOUTON) && (HIWORD(wparam) BN_CLICKED))

{

ShowWindow(Fenetre2,SW_SHOW);//afficher la fenêtre à l'écran

UpdateWindow(Fenetre2);//mise à jour de la fenêtre

}



break;



case WM_DESTROY:

PostQuitMessage(0);//arret du programme

return 0;

}

return DefWindowProc(fen,msg,wparam,lparam);

}







LRESULT CALLBACK ProcedureDeFenetre2(HWND fen,UINT msg,WPARAM wparam,LPARAM lparam)

{

switch(msg)

{



}

return DefWindowProc(fen,msg,wparam,lparam);

}



//#######################################################



Merci encore!!
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
Parce que tu t'y prend mal: au début tu crée la 2eme fenetre qui est
invisible est quand tu clique sur le bouton tu la rend visible
(ShowWindow). Mais quand tu la ferme, ca la détruit donc après
ShowWindow ne marchera pas puisque le fenêtre n'existe plus. Il faut
que tu crée la fenêtre seulement quand tu clique sur le bouton. Tu
remplace donc le ShowWindow... par le CreateWindow.

Ce que tu peux faire autrement c'est que quand tu recois WM_DESTROY
pour le deuximème fenêtre, tu la cache à ce moment la au lei de la
détruire et donc tu gardes le ShowWindow

#define ID_BOUTON 100

#define ID_BOUTON2 101



#include



LRESULT CALLBACK ProcedureDeFenetre (HWND,UINT,WPARAM,LPARAM); //prototype de la fonction de traitement des messages

LRESULT CALLBACK ProcedureDeFenetre2 (HWND,UINT,WPARAM,LPARAM); //prototype de la fonction de traitement des messages





HWND Fenetre2;

HINSTANCE hInstance2;





int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hInstancePrecedente,PSTR LigneDeCommande,int ModeAffichage)

{

char NomProgramme[ ] = "premier test";

char NomProgramme2[ ] = "deuxieme fenetre";

HWND Fenetre; //le type HWND définit un type HANDLE



HWND bouton, bouton2;

MSG Message;

WNDCLASSEX ClasseFenetre;

WNDCLASSEX DeuxFenetre;

//HINSTANCE hInstance2;



ClasseFenetre.cbSize =sizeof(ClasseFenetre);

ClasseFenetre.style = CS_HREDRAW|CS_VREDRAW;

ClasseFenetre.lpfnWndProc =ProcedureDeFenetre;

ClasseFenetre.cbClsExtra =0;

ClasseFenetre.cbWndExtra =0;

ClasseFenetre.hInstance =hInstance;

ClasseFenetre.hIcon =LoadIcon(0,IDI_APPLICATION); //LoadIcon charge un identificateur d'icone

ClasseFenetre.hCursor =LoadCursor(0,IDC_ARROW); //LoadCursor charge un identificateur de curseur

ClasseFenetre.hbrBackground =CreateSolidBrush(RGB(255,255,255)); //définit le fond d'écran de la fenêtre

ClasseFenetre.lpszMenuName =0;

ClasseFenetre.lpszClassName =NomProgramme;

ClasseFenetre.hIconSm =LoadIcon(NULL,IDI_APPLICATION);



DeuxFenetre.cbSize =sizeof(DeuxFenetre);

DeuxFenetre.style = CS_HREDRAW|CS_VREDRAW;

DeuxFenetre.lpfnWndProc =ProcedureDeFenetre2;

DeuxFenetre.cbClsExtra =0;

DeuxFenetre.cbWndExtra =0;

DeuxFenetre.hInstance =hInstance;

DeuxFenetre.hIcon =LoadIcon(0,IDI_APPLICATION); //LoadIcon charge un identificateur d'icone

DeuxFenetre.hCursor =LoadCursor(0,IDC_ARROW); //LoadCursor charge un identificateur de curseur

DeuxFenetre.hbrBackground =CreateSolidBrush(RGB(255,0,0)); //définit le fond d'écran de la fenêtre

DeuxFenetre.lpszMenuName =0;

DeuxFenetre.lpszClassName =NomProgramme2;

DeuxFenetre.hIconSm =LoadIcon(NULL,IDI_APPLICATION);



RegisterClassEx(&ClasseFenetre); //on enregistre la classe de la fenêtre

RegisterClassEx(&DeuxFenetre); //on enregistre la classe de la fenêtre



//CreateWindow va créer "visuellement" une fenetre qui utilisera la classe enregistree

Fenetre=CreateWindow(NomProgramme, //nom de la classe de fenetre


"premier programme", //titre de la fenêtre visible


WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, //style de la
fenetre


GetSystemMetrics(SM_CXSCREEN)/3, //emplacement x à l'appel


GetSystemMetrics(SM_CYSCREEN)/3, //emplacement y à l'appel


200, //taille sur l'axe x


200, //taille sur l'axe y


NULL,


NULL, //handle du menu


hInstance, //handle de l'instance (instance déclarée en haut)


NULL); //paramètres supplementaires



bouton = CreateWindowEx(0,

"BUTTON",


"salut",

WS_VISIBLE|WS_CHILD,


10,


10,


100,


35,

Fenetre,

(HMENU)ID_BOUTON,

hInstance,

NULL);



Fenetre2=CreateWindow(NomProgramme2, //nom de la classe de fenetre


"deuxieme fenetre", //titre de la fenêtre visible


WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, //style de la fenetre


(GetSystemMetrics(SM_CXSCREEN)/3)+50, //emplacement x à l'appel


(GetSystemMetrics(SM_CYSCREEN)/3)+50, //emplacement y à l'appel


200, //taille sur l'axe x


200, //taille sur l'axe y


NULL,


NULL, //handle du menu


hInstance, //handle de l'instance (instance déclarée en haut)


NULL); //paramètres supplementaires








ShowWindow(Fenetre,ModeAffichage);//afficher la fenêtre à l'écran

UpdateWindow(Fenetre);//mise à jour de la fenêtre



//Lecture d'un message dans la file d'attente

while(GetMessage(&Message,NULL,0,0))

{

TranslateMessage(&Message);

DispatchMessage(&Message);

}

return Message.wParam;

}





LRESULT CALLBACK ProcedureDeFenetre(HWND fen,UINT msg,WPARAM wparam,LPARAM lparam)

{

switch(msg)

{



case WM_COMMAND:



// Vérifie que c'est bien le bouton Vérifie si on à cliquer sur le bouton

if ((LOWORD(wparam) ID_BOUTON) && (HIWORD(wparam) BN_CLICKED))

{

ShowWindow(Fenetre2,SW_SHOW);//afficher la fenêtre à l'écran

UpdateWindow(Fenetre2);//mise à jour de la fenêtre

}



break;



case WM_DESTROY:

PostQuitMessage(0);//arret du programme

return 0;

}

return DefWindowProc(fen,msg,wparam,lparam);

}







LRESULT CALLBACK ProcedureDeFenetre2(HWND fen,UINT msg,WPARAM wparam,LPARAM lparam)

{

switch(msg)

{

case WM_DESTROY:

ShowWindow(fen, SW_HIDE);

return 0;

}

return DefWindowProc(fen,msg,wparam,lparam);

}
Messages postés
109
Date d'inscription
vendredi 8 avril 2005
Statut
Membre
Dernière intervention
15 mai 2007
1
merci en tout cas d'avoir bien voulu m'aider, je vais essayer maintenant de tout comprendre!!

++