WM_QUIT

Résolu
_michel Messages postés 77 Date d'inscription mardi 27 juin 2006 Statut Membre Dernière intervention 12 août 2010 - 16 juil. 2006 à 14:36
_michel Messages postés 77 Date d'inscription mardi 27 juin 2006 Statut Membre Dernière intervention 12 août 2010 - 18 juil. 2006 à 14:12
Voila, j'arrive pas à retrouver de message WM_QUIT dans ma "message loop".
Au lieu de ça, c'est la WindowProc qui réceptionne le message.
Pourtant, mon aide spécifie bien que WM_QUIT est un "Queued message", c'est à dire qu'il doit dabord passer dans la "thread message queue" du programme (excuser l'anglais, mon aide est en anglais et je connais pas les traductions) et donc qu'il doit se faire lire par GetMessage() dans la "Message Loop" de la WinMain.
Concretement, voila ma source :

#include <windows.h>
#include <stdio.h>



/*
 * FENETRE - Structure contenant les informations necessaires au programme
 *   sur une fenˆtre.
 */
typedef struct
{
  HWND handle;               // Handle de la fenˆtre.
  unsigned long hauteur;     // Hauteur de l'espace client.
  unsigned long largeur;     // Largeur de l'espace client.
  RECT rect;                 // Position de la fenˆtre sur le DeskTop.
  HDC contexte;              // Contexte d'affichage priv‚ de la fenˆtre.
} FENETRE;



FENETRE fenetre;





LRESULT CALLBACK WindowProc
(
  HWND hwnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam
);





long main()
{
  HINSTANCE hInstance;
  WNDCLASSEX classe;
  DWORD style, style_ex;
  MSG Msg;



  hInstance = GetModuleHandle(NULL);



  /*
   * D‚finition de la classe de fenˆtre.
   */
  classe.cbSize = 48;                       // Taille de la structure.
  classe.style = 0;                         // Style.
  classe.lpfnWndProc = (WNDPROC)WindowProc; // Fonction de traitement.
  classe.cbClsExtra = 0;                    // Octets suppl‚mentaires.
  classe.cbWndExtra = 0;                    // Octets suppl‚mentaires.
  classe.hInstance = hInstance;             // Handle du programme.
  classe.hIcon = 0;                   
  classe.hCursor = LoadCursor(NULL, IDC_ARROW);       // Curseur utilis‚.
  classe.hbrBackground = GetStockObject(NULL_BRUSH);  // Couleur par d‚faut.
  classe.lpszMenuName = NULL;               // Nom du menu.
  classe.lpszClassName = "classe_1";        // Nom de la classe de fenˆtre.
  classe.hIconSm = LoadIcon(NULL, IDI_APPLICATION);   // Icone utilis‚.



  /*
   * Enregistrement de la classe.
   */
  if(RegisterClassEx(&classe) == 0)
  {
    return(-100);
  }



  /*
   * Ajustement de la fenˆtre sur le DeskTop. (Autrement dit prise en compte
   * des bordures qui ne font pas partie de l'espace client.)
   */
  fenetre.hauteur = 100;                  // Largeur de l'espace client.
  fenetre.largeur = 150;                  // Hauteur de l'espace client.
  fenetre.rect.left = 50;                 // Coordonn‚e x.
  fenetre.rect.top = 50;                  // Coordonn‚e y.
  fenetre.rect.right = fenetre.rect.left + fenetre.largeur;
  fenetre.rect.bottom = fenetre.rect.bottom + fenetre.hauteur;
  style = WS_CAPTION |
          WS_SYSMENU;                     // Style de la fenˆtre.
  style_ex = 0;                           // Style ‚tendu de la fenˆtre.
  if
  (
    AdjustWindowRectEx
    (
      &fenetre.rect, 
      style,                  // Style de la fenˆtre.
      FALSE,                  // TRUE ou FALSE, si elle a un menu ou pas.
      style_ex                // Style ‚tendu de la fenˆtre.
    ) == (BOOL)0
  )
  {
    return(-200);
  }



  /*                                          
   * Cr‚ation de la fenˆtre.
   */
  printf("Cr‚ation.\n");
  if
  (
    (
      fenetre.handle
      =
      CreateWindowEx
      (
        style_ex,                 // Style ‚tendu.
        "classe_1",               // Classe de la fenˆtre.
        "fenetre_1",              // Nom de la fenˆtre.
        style,                    // Style.
        fenetre.rect.left,
        fenetre.rect.top,
        fenetre.rect.right - fenetre.rect.left,
        fenetre.rect.bottom - fenetre.rect.top,
        NULL,                     // Handle de la fenˆtre parente.
        NULL,                     // Handle du menu (s'il y en a un).
        hInstance,                // Handle du programme.
        NULL                      // Quelque chose de compliqu‚.
      )
    )
    ==
    NULL
  )
  {
    return(-300);
  }



  /*
   * Recherche du contexte d'affichage priv‚ de la fenˆtre.
   */
  printf("Device context.\n");  if((fenetre.contexte GetDC(fenetre.handle)) NULL)
  {
    DestroyWindow(fenetre.handle);
    return(-400);
  }



  /*
   * Affiche la fenˆtre.
   */
  printf("Affichage.\n");
  ShowWindow
  (
    fenetre.handle,
    SW_SHOWDEFAULT                                 // Type d'affichage.
  );



  /*
   * Initialise la fenˆtre.
   */
  printf("Update.\n");
  UpdateWindow(fenetre.handle);



  /*
   * Attente.
   */
  while(GetMessage(&Msg, fenetre.handle, 0, 0) == 1)
  {
    printf("Destination : %lu, Message : %lu.\n", (unsigned long)(Msg.hwnd), (unsigned long)(Msg.message));
    DispatchMessage(&Msg);
  }



  printf("Fin.\n");
  return(0);
}




 



LRESULT CALLBACK WindowProc
(
  HWND hwnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam
)
{
  printf("Destination : %lu | Message : %lu\n", (unsigned long)hwnd, (unsigned long)uMsg);



  switch(uMsg)
  {
    case WM_CLOSE:
      if(DestroyWindow(fenetre.handle) == 0)
      {
        return(-100);
      }
      return(0);



    case WM_DESTROY:
      PostQuitMessage(0);
      return(0);
  }



  return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}


Quand on appelle PostQuitMessage() ->WM_DESTROY,
on doit recevoir un message WM_QUIT.
Moi il me libère la "thread message queue" et puis c'est tout.
Comment pourrait-on faire pour le recevoir ?




 

4 réponses

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
17 juil. 2006 à 13:13
Salut,

Normalement il faut mettre NULL au deuxieme param de GetMessage() vu que c'est ta boucle de message principale.

A mon avis quand tu détruis ta fenetre, fenetre.handle devient invalide et c'est pour ca que GetMessage() retourne -1.
3
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
16 juil. 2006 à 18:38
Salut,

C'est normal, quand tu recois le WM_QUIT, GetMessage() retourne FALSE et  donc tu sors de la boucle de messages.
0
_michel Messages postés 77 Date d'inscription mardi 27 juin 2006 Statut Membre Dernière intervention 12 août 2010
17 juil. 2006 à 12:36
Salut,
en fait, ce qui se passe, c'est que la boucle ne recoit pas de WM_QUIT, mais est quitte quand même car Get Message renvoit -1 (thread queue inexistante).
Si on renplace la boucle par :

"  /*
   * Attente.
   */
  while(1)
  {
    resultat = GetMessage(&Msg, fenetre.handle, 0, 0);
    printf("Destination : %lu, Message : %lu.\n", (unsigned long)(Msg.hwnd), (unsigned long)(Msg.message));
    switch(resultat)
    {
      case 0:
        printf("Fin normale.\n");
        return(0);



      case -1:
        printf("Fin anormale : "thread message queue supprim‚e".\n");
        return(0);



      default:
        DispatchMessage(&Msg);
    }
  }"


On affiche toutjours à l'écran "Fin anormale ..."

Au début, je mettait "while(GetMessage(...))"
mais la boucle était infinie (GetMessage renvoyait toujours -1) et le programme ne terminait jamais.
0
_michel Messages postés 77 Date d'inscription mardi 27 juin 2006 Statut Membre Dernière intervention 12 août 2010
18 juil. 2006 à 14:12
C'est ça, il faut mettre NULL, car le message WM_QUIT à pour handle 0. Comme je ne prenais que les messages ayant pour handle l'handle de ma fenêtre, il ne trouvais jamais le message.
0
Rejoignez-nous