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 :

[MFC] Problème avec un splitter


Sujet :

MFC

  1. #1
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 109
    Points : 49
    Points
    49
    Par défaut [MFC] Problème avec un splitter
    Bonjour,

    J'ai une application MFC : lorsque je fais fichier -> ouvrir, cela ouvre une formview et une view séparées par un splitter.
    Jusque là tout va bien, mais quand je ferme juste cette fenêtre (pas la mainframe principale) et que je refais fichier -> ouvrir, j'ai une belle erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    " monprog.exe a rencontré un problème et doit fermer. 
    Nous vous prions de nous excuser pour le désagrément encouru."
    Je ne vois pas d'où peut venir le problème.
    Dans la fonction OnOpen() de monprogdoc.cpp appelée par fichier->ouvrir
    j'ouvre la fenêtre splittée comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    EkCreateNewWindow( ((CmonprogApp*) AfxGetApp())->m_ptFormView, this );
    voici la fonction EkCreateNewWindow :

    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
    23
     
    CFrameWnd* EkCreateNewWindow( CDocTemplate* pTemplate,
                                  CDocument* pDocument )
    {
     ASSERT_VALID( pTemplate );
     ASSERT_VALID( pDocument );
     // 1 - Create the new frame window
     // (will in turn create the associated view)
     CFrameWnd* pFrame = pTemplate->CreateNewFrame(
              pDocument, NULL );
     if( pFrame == NULL )
     {
      // Window creation failed
      TRACE0( "Warning: failed to create new frame.\n" );
      return NULL;
     }
     ASSERT_KINDOF( CFrameWnd, pFrame );
     // 2 - Tell the frame to update itself
     // (and its child windows)
     pTemplate->InitialUpdateFrame( pFrame, pDocument );
     // 3 - Return a pointer to the new frame window object
     return pFrame;
    }
    dans monprog.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     m_ptFormView = new CMultiDocTemplate(
      IDR_MESSAGE,//MAINFRAME,
      RUNTIME_CLASS(CmonprogDoc),
      // RUNTIME_CLASS(CChildFrame),
      RUNTIME_CLASS(CSplitter), 
      RUNTIME_CLASS(CMessage));
    et dans splitter.cpp

    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
    23
    24
    25
    26
     
     if (!m_wndSplitter.CreateStatic(this, 1, 2))
      // Création d’un splitter 1 ligne, 2 colonnes
     {
      TRACE0("Failed to CreateStaticSplitter\n");
      return FALSE;
     }
     if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CMessage), CSize(550, 0), pContext))
      // CSize(300,0) : Positionnement du séparateur
      // CreateView (0, 0 : Ajout du premier panneau du splitter
      // (la vue par defaut est en colonne 0)
     {
      TRACE0("Failed to create first pane\n");
      return FALSE;
     }
     
     if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CmonprogView), CSize(0, 0), pContext))
      // CreateView (0, 1 : Ajout du deuxième panneau du splitter colonne 1
     {
      TRACE0("Failed to create second pane\n");
      return FALSE;
     }
     
     SetActiveView((CView*)m_wndSplitter.GetPane(0,1));
     // rendre la vue active
     return TRUE;

  2. #2
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    Salut,

    Dans la fonction OnOpen() de monprogdoc.cpp appelée par fichier->ouvrir
    j'ouvre la fenêtre splittée comme ceci :

    Code :
    EkCreateNewWindow( ((CmonprogApp*) AfxGetApp())->m_ptFormView, this );
    La fonction OnOpen() de monprogdoc.cpp tu l'as implémenté où???
    Dans le document???
    Place d'abord des points d'arrêt pour localiser la panne.
    Puisque tu utilises Fichier->Ouvrir, as-tu mis ton doctemplate m_ptFormView dans CWinApp::AddDocTemplate() afin que MFC puisse retrouver le bon modèle dans sa liste des doctemplate et de pouvoir charger un document existant?

  3. #3
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 109
    Points : 49
    Points
    49
    Par défaut
    oui, j'implémente la fonction OnOpen() dans le document.
    J'ai placé des points d'arrêt : la panne se situe au niveau de la fonction EkCreateNewWindow.
    J'ai bien mis mon doctemplate m_ptFormView dans CWinApp::AddDocTemplate().

    Apparemment, le problème viendrait de cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ASSERT_VALID( pDocument );

  4. #4
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    Ta fonction OnOpen() est appelé directement par qui?
    Et puisque que tu as mis le doctemplate dans CWinApp::AddDocTemplate() essaie de retirer l'appel à OnOpen() et laisser MFC crée ta vue.

  5. #5
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 109
    Points : 49
    Points
    49
    Par défaut
    En fait, lorsque je lance mon application, je ne veux pas de fenêtre au démarrage, donc j'ai enlevé ces lignes de code dans monprog.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     // Parse command line for standard shell commands, DDE, file open
     CCommandLineInfo cmdInfo;
     ParseCommandLine(cmdInfo);
     // Dispatch commands specified on the command line
     if (!ProcessShellCommand(cmdInfo))
      return FALSE;
    Ma fonction OnOpen() est appelée dans la classe CMainFrame
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void CMainFrame::OnFileOpen() 
    {
     mondoc->ouvrir(); 
    }
    Le traitement est ensuite fait dans ouvrir dans la classe document.

    lorsque j'ouvre une fenêtre enfant, ça s'affiche bien sans problème mais lorque je ferme la fenetre enfant puis que j'en ouvre une autre, là ça plante.

  6. #6
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    Bon ...

  7. #7
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    Je pense que la panne se trouve ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void CMainFrame::OnFileOpen() 
    {
    mondoc->ouvrir(); 
    }
    Lorsque que tu fermes ta fenêtre enfant MDI, le document est aussi fermé (appel du destructeur du document) ce qui donne un pointeur invalide dans EkCreateNewWindow()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ASSERT_VALID( pDocument );
    Laissons la frame principale créer les frames enfants et laissons le document stocker les données.

    Et donc déplace tout ton code de EkCreateNewWindow dans CMainFrame::OnFileOpen() qui devra suivre les étapes suivantes:

    récupéré le modèle de document à partir du CWinApp
    crée l'objet document étant donné que celui meurt à la fermeture de la vue. Mais tu peux réutiliser le même document en fixant sa donnée membre m_bAutoDelete à false. Mais attention aux fuites de mémoire.
    crée la frame enfant et connecte la au document nouvellement crée.
    Ensuite tu affiches ta frame normalement avec InitialUpdateFrame().

    Dans ton code le document n'est pas crée dynamiquement par ton doctemplate mais je vois que tu l'as déclaré en tant que donné membre de ta frame. C'est une violation du modèle document-vue.

  8. #8
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 109
    Points : 49
    Points
    49
    Par défaut
    Bon, j'ai trouvé un moyen pour que ça ne plante plus : c'est de la grosse bidouille et je ne comprends même pas pourquoi ça fonctionne, mais ça fonctionne.

    Voilà la solution : j'ai juste rajouté ces 2 lignes de code dans void CMonProgDoc::ouvrir() au moment d'ouvrir le document

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     CMainFrame* pFrame;
     pFrame = new CMainFrame();
    ça marche, alors je mets résolu.

  9. #9
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    ça peu marcher mais ce n'est pas forcément bon.

    Pourquoi tu ne fais pas ce que je t'ai dit.

    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
     
    ASSERT_VALID( m_ptFormView );
     
    CDocument* pDocument = m_ptFormView->CreateNewDocument();
    ASSERT_VALID( pDocument );
     // 1 - Create the new frame window
     // (will in turn create the associated view)
     CFrameWnd* pFrame = m_ptFormView->CreateNewFrame(
              pDocument, NULL );
     if( pFrame == NULL )
     {
      // Window creation failed
      TRACE0( "Warning: failed to create new frame.\n" );
      return NULL;
     }
     ASSERT_KINDOF( CFrameWnd, pFrame );
     // 2 - Tell the frame to update itself
     // (and its child windows)
    m_ptFormView->InitialUpdateFrame( pFrame, pDocument );
     // 3 - Return a pointer to the new frame window object
     return pFrame;
    à mettre dans CMainFrame::OnFileOpen().

    Parce que là tu ouvres une seconde fenêtre principale!!!

  10. #10
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 109
    Points : 49
    Points
    49
    Par défaut
    J'ai fait comme tu as dit : ça marche aussi mais le problème, c'est qu'il m'affiche la fenêtre enfant avant d'ouvrir la boite de dialogue dans laquelle je choisi le fichier à ouvrir.

    Moi ce que je veux, c'est qu'il ouvre la boite de dialogue :
    si je choisis un fichier et je fais ok -> il affiche la fenêtre enfant avec les données du fichier chargé
    si je fais annulé, il affiche rien du tout.

    Quand je fais comme t'as dit, dans tous les cas, il affiche la fenêtre enfant, donc ça ne me convient pas vraiment.

    Je sais que c'est pas très propre, mais après tout, pour l'utilisateur final qui lancera juste l'exécutable, ce sera complètement transparent et c'est ça qui compte.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/01/2006, 14h01
  2. Réponses: 5
    Dernier message: 10/05/2005, 10h22
  3. [MFC] Problème avec un RichEdit et couleur
    Par Erakis dans le forum MFC
    Réponses: 1
    Dernier message: 24/03/2005, 14h12
  4. Problème avec les Splitter
    Par slylafone dans le forum C++Builder
    Réponses: 1
    Dernier message: 09/11/2004, 13h52
  5. [MFC] problème avec les insertions dans CComboBox
    Par Joeleclems dans le forum MFC
    Réponses: 12
    Dernier message: 11/06/2004, 15h31

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