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

MFC Discussion :

modèle View/Document : acces violation a la fermeture


Sujet :

MFC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut modèle View/Document : acces violation a la fermeture
    Bonjour,

    J'ai créé une appli sur le modèle View, Document... pour gérer plus proprement l'application mais j'ai des erreurs "Access Violation" qui apparaissent des fois quand je ferme le programme...

    J'aurais aimé vos conseils, méthodes pour bien créer une appli sur ce modèle.

    Ma question est déjà, dans quelles méthodes de View, Document, CDialog, placer les initialisations, destructions ?
    Parce que il y a les constructeurs/Destructeurs mais il y a aussi les méthodes comme OnInitialUpdate(), Destroy, etc...

    Dans quel ordre sont créées mes classes ? D'abord le Document et ensuite la View je suppose ?

    Mon projet se présente ainsi :
    - CMainFrame hérite de CFrameWnd
    - CXApp hérite de CWinApp
    - CXDoc hérite de CDocument
    - CXView hérite de CFormView

    et

    - CXDlg hérite de CDialog, => type de fenetres que j'ouvre lors d'un clic sur un élément d'une listebox.


    C'est dans la View, que je crée les CXDlg et que je stocke les pointeurs.

    Dans CXDlg, du coup, j'utilise la méthode PostNCDestroy comme préconisé dans la FAQ...
    Lors de la fermeture du programme avec des fenetres CXDlg ouvertes, on passe bien dans PostNCDestroy, mais c'est après être passées dans cette fonction pour chaque petite fenêtre ouverte que j'ai un Access Violation et le debugueur me mets sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CXDoc* CXView::GetDocument()
    {
    ASSERT(m_pDocument->isKindOf(RUNTIME_CLASS(CXDoc))); // ICI la petite flèche jaune dans Visual...
    return (CXDoc*) m_pDocument;
    }
    Le problème, c'est que je n'arrive pas à voir d'ou est appelé ce GetDocument...

    Bref, si quelqu'un a une idée et des conseils...

    Merci
    Bonne journée

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par italiasky Voir le message
    Bonjour,

    J'ai créé une appli sur le modèle View, Document... pour gérer plus proprement l'application mais j'ai des erreurs "Access Violation" qui apparaissent des fois quand je ferme le programme...
    Tu as raison. Probablement des destructions croisées ou redondantes...

    Citation Envoyé par italiasky Voir le message
    J'aurais aimé vos conseils, méthodes pour bien créer une appli sur ce modèle.

    Ma question est déjà, dans quelles méthodes de View, Document, CDialog, placer les initialisations, destructions ?
    Parce que il y a les constructeurs/Destructeurs mais il y a aussi les méthodes comme OnInitialUpdate(), Destroy, etc...
    D'abord, il faut que tu ais bien séparé les données propres au document de celles propres à l'affichage. Ensuite, quelques pistes:
    -> Dans les constructeurs sont construits et initialisées les variables membres de comportement de l'instance indépendamment du contenu du document/vue
    -> Dans OnInitialUpdate, OnNewDoc, ... seront construits les variables membres directement liées au contenu du/de la document/vue.
    Citation Envoyé par italiasky Voir le message
    Dans quel ordre sont créées mes classes ? D'abord le Document et ensuite la View je suppose ?
    Tu trouveras des informations précieuses dans le MSDN: ici (+++) et ici.
    En gros, le DocTemplate, crée un document puis la frame. La frame se charge de créer la vue.

    Citation Envoyé par italiasky Voir le message
    Mon projet se présente ainsi :
    - CMainFrame hérite de CFrameWnd
    - CXApp hérite de CWinApp
    - CXDoc hérite de CDocument
    - CXView hérite de CFormView

    et

    - CXDlg hérite de CDialog, => type de fenetres que j'ouvre lors d'un clic sur un élément d'une listebox.


    C'est dans la View, que je crée les CXDlg et que je stocke les pointeurs.
    En as-tu vraiment besoin? Il est souvent redondant de stocker les pointeurs des boites de dialogue non modal dans la fenêtre qui les a créé. Es-tu sur de ta conception?

    Citation Envoyé par italiasky Voir le message
    Dans CXDlg, du coup, j'utilise la méthode PostNCDestroy comme préconisé dans la FAQ...
    Effectivement, pour les boîtes de dialogue non modale, c'est une partique courante.

    Citation Envoyé par italiasky Voir le message
    Lors de la fermeture du programme avec des fenetres CXDlg ouvertes, on passe bien dans PostNCDestroy, mais c'est après être passées dans cette fonction pour chaque petite fenêtre ouverte que j'ai un Access Violation et le debugueur me mets sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CXDoc* CXView::GetDocument()
    {
    ASSERT(m_pDocument->isKindOf(RUNTIME_CLASS(CXDoc))); // ICI la petite flèche jaune dans Visual...
    return (CXDoc*) m_pDocument;
    }
    Le problème, c'est que je n'arrive pas à voir d'ou est appelé ce GetDocument...
    Le debugger te donne aussi la pile d'appel. Ne peux-tu la voir?

    Une piste: n'aurais-tu pas dans le destructeur de tes boîtes de dialogue un appel vers la vue? Ou un envoi de message vers cette vue?

  3. #3
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    En as-tu vraiment besoin? Il est souvent redondant de stocker les pointeurs des boites de dialogue non modal dans la fenêtre qui les a créé. Es-tu sur de ta conception?
    Et bien en fait, je vais expliquer le contexte...
    J'ai une listebox, et à chaque clic sur un item, j'ouvre une boite de dialogue qui m'affiche des détails, etc...
    Mais par exemple, si j'en ai ouvert une dizaine, au lieu de les fermer une à une, j'ai fait un bouton qui permet de fermer toutes les fenêtres ouvertes...
    Donc je n'ai pas vu d'autres solutions que de stocker les pointeurs dans un vector et d'après de les parcourir un par un pour supprimer les fenêtres avec la méthode DestroyWindow() appelée sur chaque fenêtre...
    Et donc du coup aussi, je regarde lorsqu'on ferme une fenêtre seule normalement, de supprimer le pointeur correspondant dans le vector en ayant mis des ID comme attribut pour identifier les fenêtres.

    Après, ce n'est peut être pas la meilleure façon..
    Si quelqu'un peut me dire son conseil sur la façon la plus "sure" de faire ceci... en permettant d'avoir toujours un bouton pour fermer toutes les fenêtres ouvertes d'un coup si besoin...

    Citation Envoyé par 3DArchi Voir le message
    Le debugger te donne aussi la pile d'appel. Ne peux-tu la voir?
    Je n'ai pas réussi à sortir quelque chose de bon en regardant la pile lol

    Citation Envoyé par 3DArchi Voir le message
    Une piste: n'aurais-tu pas dans le destructeur de tes boîtes de dialogue un appel vers la vue? Ou un envoi de message vers cette vue?
    Et bien en fait dans PostNCDestroy(), j'ai un appel vers la vue oui...
    En fait, je récupère le pointeur de ma vue avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CXView* pView = CXView::GetView()
    pView->removeDlgByID(this->ID);
    Donc en fait, j'ai fait une méthode static GetView pour avoir le pointeur de ma vue parce que j'en avais besoin à des endroits... mais bon ca aussi c'est peut être pas recommander lol
    Et après, donc j'appelle une méthode de ma vue ou je donne l'ID de la fenetre ouverte qui est entrain de se détruire pour qu'elle la supprime du vector...

    Bref, je crois que c'est pas très clair tout ca... lol

    Merci

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par italiasky Voir le message
    Et bien en fait, je vais expliquer le contexte...
    J'ai une listebox, et à chaque clic sur un item, j'ouvre une boite de dialogue qui m'affiche des détails, etc...
    Mais par exemple, si j'en ai ouvert une dizaine, au lieu de les fermer une à une, j'ai fait un bouton qui permet de fermer toutes les fenêtres ouvertes...
    Donc je n'ai pas vu d'autres solutions que de stocker les pointeurs dans un vector et d'après de les parcourir un par un pour supprimer les fenêtres avec la méthode DestroyWindow() appelée sur chaque fenêtre...
    Et donc du coup aussi, je regarde lorsqu'on ferme une fenêtre seule normalement, de supprimer le pointeur correspondant dans le vector en ayant mis des ID comme attribut pour identifier les fenêtres.
    Tu ne peux pas t'en sortir avec FindWindow?

    Citation Envoyé par italiasky Voir le message
    Et bien en fait dans PostNCDestroy(), j'ai un appel vers la vue oui...
    En fait, je récupère le pointeur de ma vue avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CXView* pView = CXView::GetView()
    pView->removeDlgByID(this->ID);
    Donc en fait, j'ai fait une méthode static GetView pour avoir le pointeur de ma vue parce que j'en avais besoin à des endroits... mais bon ca aussi c'est peut être pas recommander lol
    Et après, donc j'appelle une méthode de ma vue ou je donne l'ID de la fenetre ouverte qui est entrain de se détruire pour qu'elle la supprime du vector...

    Bref, je crois que c'est pas très clair tout ca... lol
    Si,si: lorsque tu quittes tu ne maîtrise pas l'ordre des fermetures. Donc ta view doit être fermée avant les boîtes de dialogues -> CXView::GetView

    Soit tu arrives à te débarrasser de ton vecteur avec FindWindow, soit tu dois blinder tes fermetures:
    -> synchroniser la fermeture de la fenêtre view avec celle des dialogues,
    -> gérer l'invalidité de la vue courante (CXView::GetView peut retourner NULL et donc à tester).

  5. #5
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Tu ne peux pas t'en sortir avec FindWindow?
    Et bien je ne sais pas trop... FindWindowEx permet d'avoir un lien sur une fenêtre en fonction du titre de la fenêtre c'est bien ca ?

    Il faudrait que je stocke les noms des titres quand même alors du coup ?

    Citation Envoyé par 3DArchi Voir le message
    Si,si: lorsque tu quittes tu ne maîtrise pas l'ordre des fermetures. Donc ta view doit être fermée avant les boîtes de dialogues -> CXView::GetView

    Soit tu arrives à te débarrasser de ton vecteur avec FindWindow, soit tu dois blinder tes fermetures:
    -> synchroniser la fermeture de la fenêtre view avec celle des dialogues,
    -> gérer l'invalidité de la vue courante (CXView::GetView peut retourner NULL et donc à tester).
    Je ne sais pas si mon problème avec la fermeture des fenêtres CDialog ou pas est réglé mais en faisant des modifs, je ne l'ai plus... enfin j'ai toujours un problème à la fermeture de ma fenêtre, mais ce n'est plus au même endroit lol

    En fait, dans ma classe MainFrm, j'ai rajouté la fonction OnClose qui est appelé au clic sur la croix rouge, et j'ai donc remis dedans l'appel à la fonction de base :
    Et c'est dans cette fonction que ca bug, très exactement à la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // close all documents first
    pApp->CloseAllDocuments(FALSE)
    Encore une histoire de fermeture de vue, document apparemment non ?

    Merci
    Bonne journée

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    1/Une façon de ne plus planter mais sans vraiment résoudre ton problème à la base est de stocker des HWND au lieu des pointeurs. Ensuite, tu peux utiliser IsWindow et DestroyWindow.
    2/FindWindow peut être utilisée uniquement avec le nom de la classe (tu dois pouvoir retrouver le nom pour une boîte de dialogue).
    3/D'ailleurs, à la réflexion, tu peux aussi passer par EnumChildWindows si toutes tes boîtes de dialogues sont fille de ta classe vue ou frame.

    Enfin, tu as clairement un problème d'ordre dans la destruction des tes éléments qui aboutit à ton problème. J'ai toujours trouvé un peu confus ces choses entre la fermeture par la petite croix rouge, par Alt+F4, par un menu etc... Ce sont souvent des aspects mal maîtrisés. As-tu regardé si la doc de farscape sur les MFC aborde ce sujet? Peut-être la solution est dedans.

Discussions similaires

  1. [WD-2010] Word - Acces - Modèle de document
    Par AidezMoiSvp dans le forum VBA Word
    Réponses: 6
    Dernier message: 20/11/2012, 11h38
  2. [POI]Utiliser des modèles de document, c'est possible ?
    Par hugo123 dans le forum Documents
    Réponses: 5
    Dernier message: 04/09/2006, 12h52
  3. Réponses: 3
    Dernier message: 13/09/2005, 12h21
  4. [Eclipse 2.1.2] Créer un modèle de document/fichier
    Par iubito dans le forum Eclipse Platform
    Réponses: 1
    Dernier message: 26/01/2005, 11h47
  5. Comment réaliser des modèles de documentations avec XML ?
    Par Dams76 dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 29/08/2003, 02h15

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