Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
1377 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [MFC] [RESOLU] Affichage message avant fermeture d une fenetre

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[MFC] [RESOLU] Affichage message avant fermeture d une fenetre

n°2267745
TP_78
Posté le 14-10-2015 à 20:34:12  profilanswer
 

Bonsoir à tous,
 
Je suis actuellement en train d'apprendre la bibliothèque objet MFC. Pour m’exercer, je teste l'affichage de messages selon différentes conditions.
Par exemple, avant l'apparition de la fenêtre principale, après la fenêtre principale, ...
 
Ce qui me pose un problème c'est d'afficher un message juste avant la fermeture de la fenêtre principale. J'ai trouvé que l'on devait utiliser WM_CLOSE cependant je n'arrive toujours pas à afficher un message juste avant la fermeture.
 
Pourriez-vous m'aider s'il vous plaît ?
 
Bonne soirée :)

Message cité 1 fois
Message édité par TP_78 le 08-11-2015 à 17:46:46

---------------
Mon topic d'achat de DRAGON QUEST http://forum.hardware.fr/hfr/JeuxV [...] 1589_1.htm
mood
Publicité
Posté le 14-10-2015 à 20:34:12  profilanswer
 

n°2267749
tpierron
Posté le 14-10-2015 à 22:33:21  profilanswer
 

TP_78 a écrit :

Bonsoir à tous,
Je suis actuellement en train d'apprendre la bibliothèque objet MFC. Pour m’exercer, je teste l'affichage de messages selon différentes conditions.
Par exemple, avant l'apparition de la fenêtre principale, après la fenêtre principale, ...
 
Ce qui me pose un problème c'est d'afficher un message juste avant la fermeture de la fenêtre principale. J'ai trouvé que l'on devait utiliser WM_CLOSE cependant je n'arrive toujours pas à afficher un message juste avant la fermeture.
 
Pourriez-vous m'aider s'il vous plaît ?
 
Bonne soirée :)


Avec l'API win32, WM_CLOSE est envoyé à la fenêtre que l'utilisateur veut fermer, mais ce message est juste une notification, au programme de faire ce qui faut pour fermer ou non la fenêtre:

  • Tu peux afficher une fenêtre de confirmation (MessageBox).
  • Tu peux fermer la fenêtre (DestroyWindow), mais continuer le programme (genre service en arrière plan).
  • Ou tu peux aussi quitter le programme si la fenêtre principale est fermée (PostQuitMessage).

Le système ne peut pas avoir connaissance de ce genre de chose, c'est pourquoi WM_CLOSE est juste une notification.
 
Si tu transmet le message a DefWindowProc(), ça sera DestroyWindow() qui sera appelé.
 
Avec les MFC, il faut surcharger OnClose(), qui appelle aussi DestroyWindow() par défaut.
 
Et puis bon, c'est mon avis à moi: mais se faire chier avec les MFC/Win32 en 2015, c'est vraiment se prendre la tête pour pas grand chose, parce que bon, même microsoft a jeté l'éponge ...

n°2267752
TP_78
Posté le 15-10-2015 à 00:05:11  profilanswer
 

Bonsoir tpierron,
 
Merci pour ta réponse.  
D'après ce que tu as dit, j'en déduis qu'il faut faire quelque chose comme ça:
 
switch(???)
{
   ...
   case WM_CLOSE: ::MessageBox(_T("La fenetre va être fermée" ));
     break;
   ...
}
 
Cependant qui retourne la notification WM_CLOSE ?


---------------
Mon topic d'achat de DRAGON QUEST http://forum.hardware.fr/hfr/JeuxV [...] 1589_1.htm
n°2267782
tpierron
Posté le 15-10-2015 à 15:20:47  profilanswer
 

TP_78 a écrit :

Merci pour ta réponse.  
D'après ce que tu as dit, j'en déduis qu'il faut faire quelque chose comme ça:
switch(???)
{
   ...
   case WM_CLOSE: ::MessageBox(_T("La fenetre va être fermée" ));
     break;
   ...
}
Cependant qui retourne la notification WM_CLOSE ?


Hmm, tu n'as pas l'air de connaître grand chose de l'API Win32/MFC. Parce que ce n'est vraiment pas le genre d'API que tu peux apprendre sur le tas, faudra t'investir un minimum, d'autant que sur internet tu ne trouveras que des exemples de culte du cargo (ce sera d'ailleurs pas beaucoup mieux sur MSDN). Si tu comptes vraiment foncer tête baissé là dedans, t'auras vraiment l'impression d'enfoncer un clou avec la tête.
 
Ton morceau de code, c'est de l'API Win32, une couche en-dessous des MFC. Avec les MFC, faut hériter d'une classe CWnd ou CDialog (la différence est importante), puis surcharger la méthode OnClose pour récupérer la notification de fermeture (qui par défaut appellera DestroyWindow).
 
Si tu veux passer par l'API Win32, ce message (WM_CLOSE) est transmis à la procédure enregistrée à la création de la classe de la fenêtre (structure WNDCLASS, champ lpfnWndProc, enregistré via RegisterClass). Cette procédure recevra une tétrachiée de notification: dans une de mes applications, le switch fait 800 lignes, et il ne contient pratiquement que des redirections.
 
Ne mélange pas les deux styles (MFC/Win32) à moins que tu saches très précisément ce que tu fais, ce qui n'est probablement pas le cas.

n°2268556
TP_78
Posté le 27-10-2015 à 12:08:25  profilanswer
 

Bonjour tpierron,
 
Si je tarde à te répondre c'est que j'ai essayé de faire ce que tu m'as dit mais je n'arrive pas à comprendre.
 
Mon programme pour l'instant se résume à un unique fichier source (main.cpp):
 

Code :
  1. #include <afxwin.h>
  2. class CTstApp : public CWinApp
  3. {
  4.   public:
  5.   BOOL InitInstance()
  6.   {
  7.     m_pMainWnd=new CWnd;
  8.     m_pMainWnd->CreateEx(0,AfxRegisterWndClass(CS_CLASSDC,0,::CreateSolidBrush(0xFF00FF),0),_T("AD-IHM" ),
  9.       WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,CRect(0,0,300,300),0,0);
  10.     m_pMainWnd->ShowWindow(m_nCmdShow);
  11.     return TRUE;
  12.   }
  13. };
  14. CTstApp NotreApp;


 
Avec mon code ci-dessus, pourrais tu m'indiquer (pas me donner la solution) comment faire s'il te plaît ?
 
En te remerciant par avance.
Bonne journée


---------------
Mon topic d'achat de DRAGON QUEST http://forum.hardware.fr/hfr/JeuxV [...] 1589_1.htm
n°2268584
Farian
Posté le 27-10-2015 à 14:24:16  profilanswer
 

Bonjour !  
 
Comme vous l'indiquait tpierron, il faudrait que votre m_pMain ne soit pas une CWnd, mais une classe à vous qui dérive de CWnd et dans laquelle vous surchargez la méthode OnClose qui est appellée automatiquement lorsque le système demande la fermeture de la fenêtre.
 
C'est dans cette méthode que vous placez votre traitement, que ce soit une fenêtre de confirmation ou toute autre action pour libérer proprement un certain nombre de ressources.
 
Bonne continuation !


Message édité par Farian le 27-10-2015 à 14:24:50
n°2268588
tpierron
Posté le 27-10-2015 à 14:59:31  profilanswer
 

Ouéééé, je viens de dépoussiérer le SDK des MFC qui moisissait depuis 2002 ou 2003, et j'avais oublié combien cette API à mal vieilli.
 
Bon, déjà, je te conseille d'utilisez le wizard de Visual Studio pour rajouter des classes, parce que les MFC rajoutent une tétrachiée de fonctions à la création. Tu m'excusera si j'ai un peu oublié de détail en 12 ou 13 ans.
 
Ton code fonctionne (ce qui est déjà pas si mal), sauf que la fenêtre s'ouvre et se ferme immédiatement. À vu de nez, je dirai qu'une méthode n'est pas surchargée comme il faut (laquelle, j'ai oublié).
 
Si tu tiens vraiment à tout gérer à la main, je te conseille vivement de laisser tomber les MFC et utiliser directement les Win32. De toute façon entre les deux, c'est choisir entre la peste ou le cholera.

n°2268784
TotalRecal​l
Posté le 29-10-2015 à 10:57:19  profilanswer
 

tpierron a écrit :


Si tu tiens vraiment à tout gérer à la main, je te conseille vivement de laisser tomber les MFC et utiliser directement les Win32. De toute façon entre les deux, c'est choisir entre la peste ou le cholera.


+1 c'est aussi ce que je me suis dit en voyant le titre du topic. Tu as vraiment besoin d'apprendre les MFC, et même les API Windows en général ? C'est dans quel but au final ?
Si le besoin est justifié et que tu ne veux pas qu'on fasse digresser le topic pas de souci [:faman:1]  


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2268977
TP_78
Posté le 02-11-2015 à 18:42:24  profilanswer
 

Merci pour vos réponses. Je fais ça et vous tiens au courant :)
 
Oui malheureusement cela est dans le cadre de mes études.
 
EDIT: Donc suite à vos réponses, j'ai surchargé ma methode OnClose cependant je ne peux pas car elle est protégée. Des suggestions ? :)
 

Code :
  1. class Fenetre : public CWnd
  2. {
  3. public:
  4. Fenetre()
  5. {
  6. }
  7. void OnClose()
  8. {
  9.  CWnd::OnClose();
  10.  MessageBox(_T("Voulez-vous fermer la fenetre ?" ), _T("TEST" ), MB_OK);
  11.  //_super::OnClose();
  12. }
  13. private:
  14. };
  15. class CTstApp : public CWinApp
  16. {
  17.   public:
  18.   BOOL InitInstance()
  19.   {
  20.   m_pMainWnd = new Fenetre;
  21.   m_pMainWnd->CreateEx(0, AfxRegisterWndClass(CS_CLASSDC, 0, ::CreateSolidBrush(0xFF00FF), 0), _T("AD-IHM" ),
  22.    WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CRect(0, 0, 300, 300), 0, 0);
  23.   m_pMainWnd->OnClose(); // Le compilateur me dit gentiment que je ne peux accèder à la fonction car elle est protegee
  24.   m_pMainWnd->ShowWindow(m_nCmdShow);
  25.     return TRUE;
  26.   }
  27. };


Message édité par TP_78 le 02-11-2015 à 19:48:49

---------------
Mon topic d'achat de DRAGON QUEST http://forum.hardware.fr/hfr/JeuxV [...] 1589_1.htm
n°2268984
tpierron
Posté le 02-11-2015 à 20:34:11  profilanswer
 

Ah ouais, quand même  :sweat: Toutes mes condoléances. Sinon, j'ai un peu revu ton code (juste la classe "Fenetre", le reste me parait bon) pour faire fonctionner le bouzin. C'est tellement dégueux, que je ne vais même pas essayer de donner des explications:

Code :
  1. class Fenetre : public CFrameWnd
  2. {
  3. public:
  4.     Fenetre() {}
  5. protected:
  6.     DECLARE_DYNAMIC(Fenetre)
  7.  
  8. // Generated message map functions
  9. protected:
  10.     afx_msg void OnClose(void);
  11.     DECLARE_MESSAGE_MAP()
  12.  
  13. };
  14.  
  15. IMPLEMENT_DYNAMIC(Fenetre, CFrameWnd)
  16.  
  17. BEGIN_MESSAGE_MAP(Fenetre, CFrameWnd)
  18.     ON_WM_CLOSE()
  19. END_MESSAGE_MAP()
  20.  
  21. void Fenetre::OnClose()
  22. {
  23.     MessageBox(_T("Voulez-vous fermer la fenetre ?" ), _T("TEST" ), MB_OK);
  24.     CWnd::OnClose();
  25. }


Quelques trucs à faire gaffe:

  • La classe de base pour une fenêtre c'est CFrameWnd, pas CWnd (oups, petit oubli)
  • J'avais oublié l'assignation à m_pMainWnd dans InitInstance, ce qui faisait que la fenêtre se fermait immédiatement.
  • Si tu redirige OnClose, faut l'appeler la classe mère après avoir demandé confirmation (MessageBox)

[:shlavos] bordel de merde, mais qu'est ce que c'est moche.

mood
Publicité
Posté le 02-11-2015 à 20:34:11  profilanswer
 

n°2269133
TP_78
Posté le 05-11-2015 à 17:17:44  profilanswer
 

Salut tpierron,
 
J'ai recopié le code que tu m'as soumis dans mon programme et j'obtiens toujours que la fonction OnClose() est protégée :/
 De ton coté cela fonctionne ?
 
Par la même occasion, pourrais tu m'expliquer à quoi correspond DECLARE_DYNAMIC() et IMPLEMENT_DYNAMIC s'il te plaît ?
 
Bonne soirée.
 
Merci de ta persévérance :)


---------------
Mon topic d'achat de DRAGON QUEST http://forum.hardware.fr/hfr/JeuxV [...] 1589_1.htm
n°2269143
tpierron
Posté le 05-11-2015 à 18:09:29  profilanswer
 

Tu parles de cette ligne dans InitInstance() :

Code :
  1. m_pMainWnd->OnClose(); // Le compilateur me dit gentiment que je ne peux accèder à la fonction car elle est protegee


Si tu cherches un moyen de fermer la fenêtre autrement que par une action de l'utilisateur, la méthode que tu cherches c'est "DestroyWindow". Cette fonction enverra une notification OnDestroy, mais pas de OnClose cela dit.
 
Si tu veux simuler un clic sur le bouton de fermeture, ça doit être un truc du genre :

Code :
  1. m_pMainWnd->SendMessage(WM_CLOSE);
  2. // Cet appel va bloquer si tu affiche un dialogue de confirmation, pour continuer malgré tout, tu peux utiliser:
  3. // m_pMainWnd->PostMessage(WM_CLOSE);


 
Edit: les macros à rajouter sont des bidules propres aux MFC, j'ai oublié le détail (ça, c'est une manière polie de dire que je ne veux pas m'en souvenir).


Message édité par tpierron le 05-11-2015 à 18:11:26
n°2269300
TP_78
Posté le 08-11-2015 à 17:42:57  profilanswer
 

Bonsoir tpierron,
 
c'est bon j'ai enfin réussi, mon objectif était de fermer la fenêtre selon que l'utilisateur clique sur X ou par une autre action.
Au final, voici mon code:  
 

Code :
  1. #include <afxwin.h>
  2. class Fenetre : public CFrameWnd
  3. {
  4. public:
  5. Fenetre()
  6. {
  7. }
  8. void OnClose()
  9. {
  10.  if (AfxMessageBox(_T("Voulez-vous fermer la fenetre 3?" ), MB_YESNO) == IDYES)
  11.  {
  12.   CWnd::OnClose();
  13.  }
  14.  //_super::OnClose();
  15. }
  16. protected:
  17. DECLARE_MESSAGE_MAP()
  18. protected:
  19. DECLARE_DYNAMIC(Fenetre)
  20. private:
  21. };
  22. IMPLEMENT_DYNAMIC(Fenetre,CFrameWnd)
  23. BEGIN_MESSAGE_MAP(Fenetre, CFrameWnd)
  24. ON_WM_CLOSE()
  25. END_MESSAGE_MAP()
  26. class CTstApp : public CWinApp
  27. {
  28.   public:
  29.   BOOL InitInstance()
  30.   {
  31.   /*m_pMainWnd=new CWnd;
  32.     m_pMainWnd->CreateEx(0,AfxRegisterWndClass(CS_CLASSDC,0,::CreateSolidBrush(0xFF00FF),0),_T("AD-IHM" ),
  33.       WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,CRect(0,0,300,300),0,0);
  34.     m_pMainWnd->ShowWindow(m_nCmdShow);*/
  35.   AfxMessageBox(_T("Fenetre 1" ), MB_OK);
  36.   m_pMainWnd = new Fenetre;
  37.   m_pMainWnd->CreateEx(0, AfxRegisterWndClass(CS_CLASSDC, 0, ::CreateSolidBrush(0xFF00FF), 0), _T("AD-IHM" ),
  38.    WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CRect(0, 0, 300, 300), 0, 0);
  39.   m_pMainWnd->ShowWindow(m_nCmdShow);
  40.   AfxMessageBox(_T("Fenetre 4" ), MB_OK);
  41.     return TRUE;
  42.   }
  43. };
  44. CTstApp NotreApp;


 
Merci beaucoup à Farian et surtout à tpierron de m'avoir aidé :)
Aller hop, c'est parti pour la prochaine étape !


---------------
Mon topic d'achat de DRAGON QUEST http://forum.hardware.fr/hfr/JeuxV [...] 1589_1.htm

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [MFC] [RESOLU] Affichage message avant fermeture d une fenetre

 

Sujets relatifs
[ERROR] Insertion de message dans tab de char ?java virtual machine dans une fenêtre tkinter
affichage tableaux apres choix select dynamiqueAffichage caractères spéciaux pose problèmes
Ligne d'affichage étrange ('set', 'anonymizeIp', true);Action dans une fenetre precise?
[résolu] Affichage de photo avec IF sur base[c] l'affichage de ces mini programmes
Problème d'affichage de caractèreafficher la fenêtre dans une applet
Plus de sujets relatifs à : [MFC] [RESOLU] Affichage message avant fermeture d une fenetre


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR