IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API graphiques Discussion :

[PB de fermeture] Un défi pour programmeurs !


Sujet :

API graphiques

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut [PB de fermeture] Un défi pour programmeurs !
    Bonjour


    Je suis confronté au problème suivant, avec mon application DirectX 9. Lorsque je suis en mode release, et que j'appuie sur ALT+F4, l'application semble se fermer. Seulement, en regardant dans le gestionnaire de tâches, elle est encore là, et après quelques tests j'ai vu que la boucle générale était toujours active. Des tests suivants m'ont appris que le message WM_QUIT n'a tout s'implement jamais été capté par ma boucle de message.

    Cette boucle est pourtant normale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    	bool g_CallLoop=true;
     
    	while( g_CallLoop )
    	{
     
    		if( PeekMessage(&Msg,NULL,0,0,PM_REMOVE) )
    		{
    			TranslateMessage(&Msg);
    			DispatchMessage(&Msg); 
    		}
    		else		
    			if( !Update() ) 
    				g_CallLoop = false;
     
    	}
    (Pour info, le WM_QUIT traité met g_CallLoop à false.)

    Et, dernier élément pour me rendre encore plus perplexe : en debug, ce problème n'apparaît pas, le WM_QUIT est capté parfaitement !

    J'ai posté ce message sur directx car ça ne m'était jamais arrivé avant, sur de la pure api windows (problème de traitement des messages en mode release, genre interceptés par directx ?). J'attends vos commentaires avec impatience !

  2. #2
    Membre averti Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Points : 358
    Points
    358
    Par défaut
    Verifie les messages reçus ( peekmessage no remove) avant le translate/dispatch et verifie que ta boucle voie le message arriver ?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    On ne voit pas le message arriver en release (mais en debug si, et c'est pour ça que ça marche).

    J'ai trouvé un moyen d'arrêter le jeu malgré tout, c'est d'ajouter un test du genre IsWindow( handle sur la fenêtre ) dans les conditions de continuation de la boucle, mais ça n'explique pas le problème !

  4. #4
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    A chaque fois que j'ai eu ce genre de comportement dans une application directx (exe toujours présent dans le gestionnaire de tâche, mais fenêtre détruite), c'est parce qu'il y avait un problème de release, des objets ne sont pas détruits. Si tu programmes en C++, vérifies que les destructeurs sont tous appelés, et que tu "releases" bien toutes les interfaces directx.

    PS: pour le mode release, une petite MessageBox dans le destructeurs...
    PS2: souvent le problème n'apparaît pas en mode debug parce que le compilateur se charge lui-même de tout nettoyer.
    PS3: est-ce que ton programme est multithreadé? Ca expliquerait que le test "IsWindow" résolve ton problème, et je pourrais t'expliquer ce qui se passe.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    Le programme n'est pas multithreadé, et pourtant WM_QUIT n'est pas capté par le programme (test avec un point d'arrêt bien placé dans la fonction WndProc).

    J'ai par ailleurs bien vérifié, et les ressources sont totalement supprimées lorsque l'on capte WM_QUIT. En effet, le programme est parfaitement terminé quand on le quitte par la voie normale (bouton "quitter le jeu"), et c'est la même portion de code utilisée pour un WM_QUIT qui serait capté.

  6. #6
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Ce ne sont que quelques remarques (pas sûr qu'elles aient un quelconque effet sur le programme):

    1) Est-ce que tu peux mettre g_CallLoop en volatile (sinon son accès risque fort d'être optimisé par le compilateur).

    2) C'est de la cruauté, je sais mais...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     bool wannaQuit = false;
     do
     {
       if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
       {
         if (Msg.message == WM_QUIT)
         {
           wannaQuit = true;
         }
         else
         {
           TranslateMessage(&Msg);
           DispatchMessage(&Msg);
         }
       }
       else
       {
         Update();
       }
     }
     while (!wannaQuit);
    est plus lisible ET plus correct - pas besoin de te préoccuper du traitement de WM_QUIT dans ta wndProc (qui n'est d'ailleurs pas faite pour ça; le message WM_QUIT n'est pas prévu pour être traité dans une wndProc puisque toutes fenêtres sont censées avoir été détruites lorsque tu le reçois). Comme le dit le MSDN :

    Return Value
    This message does not have a return value because it causes the message loop to terminate before the message is sent to the application's window procedure.

    Remarks
    The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  7. #7
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Points : 5 323
    Points
    5 323
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    1) Est-ce que tu peux mettre g_CallLoop en volatile (sinon son accès risque fort d'être optimisé par le compilateur).
    la variable est modifié dans la boucle, ce serait donc une erreur du compilo si il fait des optimisations étranges dessus...
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

  8. #8
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par bafman Voir le message
    la variable est modifié dans la boucle, ce serait donc une erreur du compilo si il fait des optimisations étranges dessus...
    Toutes mes confuses
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Des tests suivants m'ont appris que le message WM_QUIT n'a tout s'implement jamais été capté par ma boucle de message.
    Comment veux-tu capter le message WM_QUIT s'il n'est pas envoyé par PostQuitMessage ?

    WM_QUIT Notification

    The WM_QUIT message indicates a request to terminate an application and is generated when the application calls the PostQuitMessage function.
    It causes the GetMessage function to return zero.
    C'est WM_CLOSE qui est envoyé à la boucle de message et non WM_QUIT si on fait ALT F4

    The WM_CLOSE message is sent as a signal that a window or an application should terminate.

    An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE message and calling the DestroyWindow function only if the user confirms the choice.

  10. #10
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    pas besoin de te préoccuper du traitement de WM_QUIT dans ta wndProc (qui n'est d'ailleurs pas faite pour ça; le message WM_QUIT n'est pas prévu pour être traité dans une wndProc puisque toutes fenêtres sont censées avoir été détruites lorsque tu le reçois).
    Oui et non .
    WM_QUIT est placé dans la WndProc si on appelle PostQuitMessage()...ce qui ne semble pas être le cas ici .
    Dans un jeu la logique toute bête serait : l'utilisateur clique quelque part sur "terminer" ou bien il presse la touche ESCAPE ( récupérée par WM_KEYDOWN) .
    Puis ensuite le traitement de WM_QUIT permet d'effacer les objets alloués et autre..
    Par exemple dans la boucle de message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    switch ( message)
    {
    case WM_KEYDOWN:
    switch ( wParam)
    {
    case VK_ESCAPE:PostQuitMessage(0);break;// Windows place alors WM_QUIT
     
    } 
    break;
    case WM_QUIT:
    DesallouerObjets();
    FaireQQueChose();
    break ;

  11. #11
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Allo y'a quelqu'un ?As-tu résolu le problème alors ?

  12. #12
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    Désolé pour cette longue absence, le problème est résolu grâce à vos remarques (notamment le code de Mat.M, plus propre). Cependant je ne sais pas pourquoi il se produisait en release et pas en debug.
    Merci en tout cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Le sudoku, un vrai défi pour programmeur
    Par ChPicard dans le forum Langages de programmation
    Réponses: 0
    Dernier message: 18/06/2010, 04h20
  2. Livre ou logiciel pour programmeur débutant
    Par Linka dans le forum Débuter
    Réponses: 9
    Dernier message: 19/12/2006, 16h45
  3. Un défi pour des pros
    Par Total_amateur dans le forum Langage
    Réponses: 9
    Dernier message: 17/10/2006, 10h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo