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] MDI avec 1 seul document à la fois


Sujet :

MFC

  1. #1
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut [MFC] MDI avec 1 seul document à la fois
    Salut,

    Voilà, j'aimerais limiter mon application MDI pour que l'utilisateur ne puisse ouvrir qu'un seul document à la fois... (oui oui, c'est bien une MDI que je veux quand meme )

    Après pas mal de recherche, j'ai bien compris que la méthode simple consistait à redéfinir les méthodes OnFileNew et OnFileOpen de CMyApp, mais je suis coincé ... [j'ai vu aussi une méthode compliquée en redéfinissant CMultiDocTemplate, mais bon ...]

    Comment faire par exemple pour fermer le document courant si il y en a un ? Et pour récuperer le document créé par mon appel a CWinApp::OnFileNew ou CWinApp::OnFileOpen.

    De même, si je reussi finalement à appeler OnCloseDocument() sur le document courant, comment faire pour savoir si l'utilisateur n'a pas par hazard annulé (si le document avait été modifié par exemple) ?

    Enfin beaucoup de question pour un pb qui n'est peut être pas très compliqué

    Merci pour toutes vos idées!

    bigquick

  2. #2
    mat.M
    Invité(e)
    Par défaut
    I don't understand , no comprendo , une appli MDI c'est fait pour ouvrir plusieurs fenêtres en même temps !
    Sinon projet SDI !

  3. #3
    Membre éclairé
    Avatar de matazz
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    471
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 471
    Points : 668
    Points
    668
    Par défaut
    t'as qu'a faire une SDI...
    Non je déconnes...
    C'est quoi qui t'oblige à faire un MDI ?

  4. #4
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    En fait, si j'ai besoin d'une application MDI, c'est pour pouvoir ouvrir un document, et avoir plusieurs vues dessus (donc plusieurs ChildFrames ouvertes dans la MainFrame).

    Donc au final, j'aurai ma fenêtre principale, avec un menu, et à l'interieur, plusieurs fenêtre correspondant non pas à des documents différents, mais à plusieurs vues du même document.... d'où l'intérêt de n'ouvrir qu'un document à la fois, pour pas que l'utilisateur s'y perde (du genre "à quelle document correspond cette fenêtre??")

    Peut être que je me trompe, mais je crois que ce n'est pas possible avec une SDI...

  5. #5
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    peut etre l'aspect visuel ...
    et surtout avoir plusieur tamplate de fenetre possible mais un a la fois ,
    donc MDI obligatoire ...

    Note que en partant de ce post de la faq:
    http://c.developpez.com/faq/vc/?page=CWinApp#GetAllView
    il ne devrait etre dur de savoir combien il y a de fenetre view en cours dans l'application ...


  6. #6
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Super, merci pour le lien, visiblement on peut accéder aux documents du document template, donc je n'ai plus qu'à tester si il en existe un, et puis à demander sa fermeture (avec confirmation si le flag Modified est à TRUE).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    POSITION pos2 = pTemplate->GetFirstDocPosition();
    while (pos2)
    {
        CDocument* pDoc = pTemplate->GetNextDoc(pos2);
        ASSERT(pDoc);
    }
    Par contre est-ce que tu vois comment faire pour tester si la fermeture du document à vraiment eu lieu ? (OnCloseDocument retourne void, mais c'est peut -être parceque la verification du flag est faite en amont, ...)

  7. #7
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut tu cherches a faire quoi exactement ?

  8. #8
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Salut

    C'est vrai je n'ai peut être pas été très clair.

    Alors, je voudrais interdire à l'utilisateur d'avoir plusieurs documents ouverts à la fois. Donc, sur OnFileNew et OnFileOpen, je verifie si il y a déjà un document ouvert ... jusque la tout va bien

    Maintenant, s'il y a déjà un document ouvert, je voudrais:
    - le fermer
    - en demandant confirmation s'il y a eu des modifications

    (donc le comportement par défault quand on ferme un document avec Fichier->Fermer)

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    alors pour savoir si un document est modifié:
    CDocument::IsModified
    BOOL IsModified( );
    pour fermer la child associée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    POSITION pos = pDoc->GetFirstViewPosition();
    CView* pView = pDoc->GetNextView(pos);
    if(pView) pView->GetParentFrame()->PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);

  10. #10
    Membre éclairé
    Avatar de matazz
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    471
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 471
    Points : 668
    Points
    668
    Par défaut
    Citation Envoyé par bigquick
    ...
    Donc au final, j'aurai ma fenêtre principale, avec un menu, et à l'interieur, plusieurs fenêtre correspondant non pas à des documents différents, mais à plusieurs vues du même document....

    Peut être que je me trompe, mais je crois que ce n'est pas possible avec une SDI...
    Peut-ête que je me trompe aussi, mais avec un SDI et des CSplitterWnd tu paut avoir plusieurs vues pour ton document...

    Cela dit apprement t'as trouvé de quoi regler ton pbm...

  11. #11
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Merci bcp, je vais tester ca (à première vue ca fonctionne, mais il me redemande si je veux enregistrer le doc quand je ferme mon appli : )

    Sinon pour les MDI c'est plutôt pour l'aspect ergonomie, et pour avoir accès au système Document/View/DocumentTemplate qui me facilite l'architecture

    Donc à mon avis, ce post est résolu, je vérifie ça dès que j'ai mangé

    ps: Question bonus quelle est la différence entre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pView->GetParentFrame()->PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pView->GetParentFrame()->SendMessage(WM_CLOSE);
    ?

  12. #12
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    pour le flag tu rajoutes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pdoc->SetModifiedFlag(FALSE);
    et la plus de question ...
    le sc_close simule le clic sur la croix ...

  13. #13
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Aie,

    En fait, comme je peux avoir plusieurs vues ouvertes sur mon document, il faudrait envoyer un CLOSE à toutes les vues associées. Je pense que c'est dommage, puisque CDocument::OnCloseDocument() s'occupe justement de fermer toutes les vues associées.

    N'y a-t-il pas moyen de fermer le document directement, toujours en demandant confirmation (et non pas les frames des vues de ce document) ?

    En fait je cherche à appeler le code qui est appelé quand on fait Fichier->Fermer (mais je ne vois aucun appel à ce code, et d'ailleurs dans le ClassWizard, il n'y a pas de fonction associée à "Command" pour cet élément du menu ).

  14. #14
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    et bien ou est le pb ?
    tu iteres sur toutes les vues du document :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    POSITION pos = pdoc->GetFirstViewPosition();
       while (pos != NULL)
       {
          CView* pView = pdoc->GetNextView(pos);
         pView->GetParentFrame()->PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);
       }
    non ?


  15. #15
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut [Résolu] [MFC] MDI avec 1 seul document à la fois
    En fait, dans la fonction OnSave du document, je sauvegarde toutes les vues ouvertes pour les rouvrir la fois d'après (donc dans le fonction OnOpen ). Donc ca m'embétait de les fermer avant de fermer le document...

    Mais finalement avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pDoc->OnCmdMsg(ID_FILE_CLOSE, 0, 0, 0);
    tout va bien: ca appelle la fermeture du document (avec sauvegarde si besoin est), puis les vues sont fermées. Et après je n'ai plus qu'à créer un nouveau document...

    Merci bcp en tout cas, j'ai appris bcp de choses aujourd'hui

  16. #16
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Dès que j'ai trouvé comment passer le sujet en résolu, je le fais

  17. #17
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    ben le bouton en bas a gauche

  18. #18
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Ah oui en effet
    Mais chez moi l'image ne s'affiche pas, il est dur a repérer

    ps (le dernier, promis)
    Est-ce que c'est normal qu'un document fermé ne se retire pas de la liste des documents du "document template" ?
    J'ai été obligé de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void CMMDoc::OnCloseDocument() 
    {
    	// retirer le document du "document template"
    	GetDocTemplate()->RemoveDocument(this);
     
    	// appeler la methode de base
    	CDocument::OnCloseDocument();
    }

  19. #19
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    normalement le traitement est fait dans l'appel de la fonction de la classe de base :
    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
    27
    28
    29
    30
     
    void CDocument::OnCloseDocument()
    	// must close all views now (no prompting) - usually destroys this
    {
    	// destroy all frames viewing this document
    	// the last destroy may destroy us
    	BOOL bAutoDelete = m_bAutoDelete;
    	m_bAutoDelete = FALSE;  // don't destroy document while closing views
    	while (!m_viewList.IsEmpty())
    	{
    		// get frame attached to the view
    		CView* pView = (CView*)m_viewList.GetHead();
    		ASSERT_VALID(pView);
    		CFrameWnd* pFrame = pView->GetParentFrame();
    		ASSERT_VALID(pFrame);
     
    		// and close it
    		PreCloseFrame(pFrame);
    		pFrame->DestroyWindow();
    			// will destroy the view as well
    	}
    	m_bAutoDelete = bAutoDelete;
     
    	// clean up contents of document before destroying the document itself
    	DeleteContents();
     
    	// delete the document if necessary
    	if (m_bAutoDelete)
    		delete this;
    }
    avec le delete this on a dans le destructeur:
    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
     
    CDocument::~CDocument()
    {
    	// do not call DeleteContents here !
    #ifdef _DEBUG
    	if (IsModified())
    		TRACE0("Warning: destroying an unsaved document.\n");
    #endif
     
    	// there should be no views left!
    	DisconnectViews();
    	ASSERT(m_viewList.IsEmpty());
     
    	if (m_pDocTemplate != NULL)
    		m_pDocTemplate->RemoveDocument(this);
    	ASSERT(m_pDocTemplate == NULL);     // must be detached
    }
    un dernier truc pour tout fermer tu pouvais appeler direct OnFileClose()
    du document plutot que d'envoyer un message ....


  20. #20
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Ah ok !

    Merci bcp pour ce code, je comprends mieux.
    En effet, dans mon document m_bAutoDelete = FALSE, donc il ne se détruisait pas, et donc ne se retirait pas du document template.

    Par contre je n'arrive pas a appeler CDocument::OnFileClose(), c'est une méthode protégée non ?

    Sinon, comment fais tu pour accéder au code des classes de base (je ne dois pas être très doué...). Je voudrais bien voir celui de CView opur comprendre ce qui fait que même avec m_bAutoDelete=FALSE, le fait de fermer la dernière vue me demande si je sauvegarder le document ?

    Merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [VB.NET] Checkedlistbox avec 1 seule valeur à la fois
    Par lecknaat dans le forum Débuter
    Réponses: 1
    Dernier message: 28/06/2013, 13h34
  2. [MFC-MDI] Accéder au document depuis une ChildFrame
    Par stratocastom dans le forum MFC
    Réponses: 3
    Dernier message: 03/12/2010, 09h29
  3. [MFC]MDI - switcher des documents
    Par Nemehy dans le forum MFC
    Réponses: 4
    Dernier message: 30/03/2006, 17h20
  4. Réponses: 18
    Dernier message: 06/10/2005, 10h09
  5. Réponses: 3
    Dernier message: 09/02/2005, 17h43

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