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 :

récupérer un pointeur sur une classe qui hérite de CView


Sujet :

MFC

  1. #1
    Membre du Club
    Inscrit en
    Mars 2005
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 79
    Points : 46
    Points
    46
    Par défaut récupérer un pointeur sur une classe qui hérite de CView
    Bonjour,

    je me demandai s'il est possible de récupérer un pointeur sur une classe qui hérite de CView au niveau de la classe de l'application (celle qui hérite de CWinApp).

    J'ai déjà vu dans les faq qu'on pouvait récupérer un pointeur sur une CView (pour parcourir toutes les view), mais je ne vois pas comment faire pour les classes qui en héritent.

    Pourriez-vous m'éclairer?

  2. #2
    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
    Ben si ta classe hérite de CView, tu fait un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this->GetNextView(ViewPos);
    dans ton doc et apres tu caste ton oblet CView en un objet de ta classe CMyView...
    Qui va piano va sano...

  3. #3
    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 le matin, j'ai peut-être les idées embrouillées mais tu n'utilise jamais de CView de base normalement. Tu en hérites forcément...
    Donc je dirais que si tu n'as qu'un seul type de vue (celle qui hérite de CView), alors tu peux simplement parcourir les vues (avec le code que tu as trouvé) et caster les pointeurs reçus en CTaView.

    Si par contre il y a plusieurs types de vues, je ne vois pas de moyen facile d'accéder à un type de vue (ou à une vue) en particulier.

    Qu'est-ce que tu veux faire exactement ?
    And still we will be here, standing like statues ...

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2004
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    En tout cas si il a plusieurs type de vues, le polymorphisme serait possible dans ce cas? Faire un vecteur de type de vues de base (TaView) qui fait des fonctions virtuelles et dans ce vecteur tu mets des TaView2 qui herite de TaView etc et chaqune des spécifications de TaView définit sa propre fonction, virtuelle chez TaView

  5. #5
    Membre du Club
    Inscrit en
    Mars 2005
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 79
    Points : 46
    Points
    46
    Par défaut précisions
    Je travaille sur une application SDI. Cela m'a permis d'avoir automatiquement 1 classe CWinApp, une classe CView, une classe CDocument et une classe CFrameWnd.

    J'ai un seul document template, par contre j'ai splitté ma CMainFrame avec un Splitter Static et j'ai créé de nouvelles classes View. Du coup je me retrouve avec à la fois la classe View qui a été créé automatiquement et celles que j'ai rajoutées. (Je ne sais pas si ce que j'ai fait est très propre d'ailleurs...)

    Extraits de mon code :

    Ca c'est ce qui a été créé automatiquement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CSingleDocTemplate* pDocTemplate;
    	pDocTemplate = new CSingleDocTemplate(
    		IDR_MAINFRAME,
    		RUNTIME_CLASS(CValidProd3Doc),
    	    RUNTIME_CLASS(CMainFrame),// main SDI frame window
    		RUNTIME_CLASS(CValidProd3View));
    	AddDocTemplate(pDocTemplate);
    J'ai rajouté une classe qui hérite de CFormView que j'ai appelé :
    CInterractiveView (elle n'est pas rajoutée dans un Doc template ou truc du genre)

    J'aimerai pouvoir récupérer dans mon application des pointeurs aussi bien sur me classe CValidProd3View et CInterractiveView.

    Voilà ce que j'ai fait : (le code a été copier puis adapter à partir de la faq)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    		CWinApp* pApp = AfxGetApp();        
    		CDocTemplate* pTemplate;
    		POSITION pos = pApp->GetFirstDocTemplatePosition();
    		ASSERT(pTemplate);
    		POSITION pos2 = pTemplate->GetFirstDocPosition();
            CDocument* pDoc = pTemplate->GetNextDoc(pos2);
            ASSERT(pDoc);
            POSITION pos3 = pDoc->GetFirstViewPosition();
            CView* pView = pDoc->GetNextView(pos3);
    		CValidProd3View* pValidView = (CValidProd3View*)(pView);
    Le code compile bien et sans warnings (remarque je ne sais même pas si j'affiche tous les warnings ;-p ) Par contre quand j'arrive dans le bout de code ci dessus, ça plante méchamment...


  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2004
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    Quand tu dis rajouter, tu dis hériter de celle que VC++ t'as faite?... Ou alors c'est toi qui a hérité des View sur ce quoi VC++ à hérité ta view principale?

    Car normalement, si chacune des vues à des fonctions de bases, c'est pas difficile... Il faut que tu fasse un vecteur de la classe de base de tes View... mais rend la abstraite (par fonctions virtuelles et une virtuelle pure si ça fonctionne pas) et spécialise alors chacun des fonction dans chaque classe (View) qui hérite de la principale...

    Tu vois :s???....

  7. #7
    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
    Beh en fait, si tu as plusieurs types de vues, tu ne peux pas caster la CView en CValidProd3View, tout simplement parceque c'est peut être une CInterractiveView.

    La solution du polymorphisme est, je pense, pas mal. Ajoutes simplement une classe intermédiaire entre CView et CValidProd3View (ou CinteractiveView), qui définit tout ce qu'on peut faire sur tes vues (en général), et après tu n'as plus qu'à caster le CView en CViewIntermediaire.


    Juste une question au passage, pourquoi ne rajoutes-tu pas un document template pour le 2ème type de vue ? Ca te permettrait d'instancier ces vues facilement. Par contre, n'appelle pas AddDocTemplate(pDocTemplate2); pour le second template, ça ne sert à rien (et pense à le deleter dans OnDestroy ).
    And still we will be here, standing like statues ...

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2004
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    J'explique un peu le polymorphisme rapidement :

    Tu as une classe Mammifère...

    Tu veux te faire un zoo imaginons... et tu déclare donc un vecteur de mammifères :

    vector<Mammifere> zoo;

    Mais, tu te dis que Mammifère est trop général et tu veux heriter

    class Lion : public Mammifere
    class Tigre : public Mammifere

    Mais là, tu te dis... oui, mais comment je fais pour foutre dans un vecteur???

    Alors déjà, dans Mammifere :
    - fonctions virtuelles : virtual taFct();
    - une virtuelle pure : virtual taFct()=0;

    Ensuite, redéfinir tes fonctions virtuelles dans tes classes héritées si tu as envie...

    Et ensuite :

    vector<Mammifere *> zoo;

    Ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      class Mammifere{
             virtual taFct()=0;
             ...
             virtual taFct2();
      }
     
      class Lion : public Mammifere{
            taFct();
            taFct2();
      }
    Et ensuite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       vector <Mammifere *> zoo;
       Lion * lion = new Lion(...);
       zoo.push_back(lion);
    etc... et voilà, un vecteur qui contient plein de sortes de classes héritées de Mammifere...

    Qu'on me corrige au cas ou...

  9. #9
    Membre du Club
    Inscrit en
    Mars 2005
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 79
    Points : 46
    Points
    46
    Par défaut réponse
    Oulala...
    Pour répondre à DarkWiven, je dirai que mes classes View héritent soit de CView, soit de CFormView, mais n'ont pas d'autres liens entre elles. En gros, celle qui a été créée automatiquement hérite de CView et celles que j'ai rajoutées héritent de CView ou de CFormView.

    Ceci dit, ça m'a pas l'air idiot du tout le truc que tu proposes. (Je vérifie si j'ai bien compris.) En gros ce que je peux faire c'est :
    -déclarer ma classe ValidProd3View en abstraite et définir tout un tas de méthodes sympa dedans.
    -faire hériter mes autres View de celle-ci et surcharger les méthodes virtuelles dedans.
    -du coup, je garde le même code pour récupérer les pointeurs sur une ValidProd3View.
    -Enfin j'utilise la méthode IsKindOf pour vérifier que j'ai bien telle ou telle vue. (je ne suis pas sûr de ce dernier point.)

    Pour répondre à la question de bigquik :
    "Juste une question au passage, pourquoi ne rajoutes-tu pas un document template pour le 2ème type de vue ? Ca te permettrait d'instancier ces vues facilement. Par contre, n'appelle pas AddDocTemplate(pDocTemplate2); pour le second template, ça ne sert à rien (et pense à le deleter dans OnDestroy )."

    Ben, je sais pas trop...
    (J'apprends sur le tas en VC++ et bcp grace à ce site) Je n'ai pas très très bien compris les docTemplate. Quel est l'intéret des doc template? En quoi cela me permettrait-il d'instencier les vues facilement???

    Merci pour vos réponses

    PS : C'est génial le coup de la balise code.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2004
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    Le polymorphisme est certes très très utile, mais utiliser avec prudence. Mais entre guillemet, je répète ce que tu as dis pour confirmer :

    Une classe de base abstraite (fct virtuelles et une pure)
    Des classes qui en hérite et qui définisse ces fonction à leur manière
    Et en dernier, le mieux, faire un vecteur qui ramassera chaque instanciation de ces classes qui héritent (un vecteur de la classe de base en pointeur), sinon ça fonctionne aussi de faire direct des conversions, mais là c'est cho cho quand même (ça dépend le sens de la conversion).
    + ce que j'ai dis moi ^^

    Attention : les fct virtuelles et les pures doivent avoir une définition aussi...

    Au cas ou, que quelqu'un me dise si j'ai fait des fautes qque part, et aussi, je te conseille de te documenter aussi dessus, niveau syntaxe car pê j'ai oublié qqchose.

  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
    En fait, je ne sais pas comment tu créés tes différentes vues, mais un DocTemplate te permet de créer des documents et des vues en dehors des trucs standards Fichier->Nouveau ou Fichier->Ouvrir.

    Ca n'arrive peut être pas fréquemment de créér un document sans passer par le menu, mais pour les vues ça peut etre pratique, par exemple pour ouvrir une nouvelle vue (ou pourquoi pas 2 vues de type différents) sur un document existant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	CFrameWnd* pFrame = m_pDocTemplate->CreateNewFrame(pDoc,NULL);
     
    	// erreur si la creation échoue
    	if(pFrame==NULL)
    	{
    		AfxMessageBox("Impossible de créér une nouvelle vue",MB_OK | MB_ICONERROR);
    		return;
    	}
     
    	// on init la frame : appelle OnInitialUpdate() de la vue
    	m_pDocTemplate->InitialUpdateFrame(pFrame,pDoc);
    Ici pDoc est le pointeur sur le document sur lequel tu veux voir à travers la vue. Ca peut être un document déjà existant (que tu auras stocké quelquepart), ou un document que tu viens de créér avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CMyDoc* pDoc = m_pDocTemplate->CreateNewDocument();
    ou encore NULL, si la vue n'a pas encore de document associé...

    Regarde ce lien-là pour avoir plus de détails
    http://msdn.microsoft.com/library/de...ocTemplate.asp
    And still we will be here, standing like statues ...

  12. #12
    Membre du Club
    Inscrit en
    Mars 2005
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 79
    Points : 46
    Points
    46
    Par défaut arg...
    En fait, c'est pas si simple que ça...

    Certaines de mes classes héritant de CView et d'autres de CFormView...

    Du coup il faut que ma classe abstraite hérite de CView et que mes autres classes héritent
    soit :
    juste de ma classe abstraite
    soit
    de ma classe abstraite et de CFormView à la fois. (De plus CFormView hérite aussi de CView)

    Bref, ça fout un peu la merde dans mon code et je me demande s'il ne serait pas plus simple de faire comme suit :

    Je récupère des pointeurs de type CView. Je vérifie quelle est la classe avec la méthode IsKindOf. Si ça renvoie la bonne classe je fais un cast. Comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    					if(pView->IsKindOf(RUNTIME_CLASS(CInterractiveView)))
                    {
                      CInterractiveView * pintView = (CInterractiveView*)(p);
    						pintView->Test();
     
                    }
    Je me demande juste si les cast comme ça ne risque pas de faire planter mon code au bout d'un moment... Ca marche bien les cast comme ça???

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2004
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    MMMhhh, moui... j'm'y connais pas en vue, mais si tu veux en gerer plusieurs à caractère différents et voir laquelle est-ce, c'est bon comme ça je crois...

  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
    salut,
    j'arrive apres la bataille ,
    en SDI c'est assez simple :
    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
     
    // extrait de CMainFrame pour la creation du splitter
        //if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CSdiSplitterView), CSize(100, 100), pContext) ||
        //    !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMyFormView), CSize(100, 100), pContext))
     
        // code a placer n'importe ou :
        CMainFrame *pFrame=static_cast<CMainFrame *>(AfxGetMainWnd());
     
        CSdiSplitterView *pFirstView=static_cast<CSdiSplitterView *>(pFrame->m_wndSplitter.GetPane(0,0));
        ASSERT(pFirstView->IsKindOf(RUNTIME_CLASS(CSdiSplitterView)));
     
        // verification de la classe de base pour l'exemple
        ASSERT(pFirstView->GetRuntimeClass()->IsDerivedFrom(RUNTIME_CLASS(CListView)));
     
     
        CMyFormView *pEndView=static_cast<CMyFormView *>(pFrame->m_wndSplitter.GetPane(0,1));
        ASSERT(pEndView->IsKindOf(RUNTIME_CLASS(CMyFormView)));
     
        // verification de la classe de base
        ASSERT(pEndView->GetRuntimeClass()->IsDerivedFrom(RUNTIME_CLASS(CFormView)));
    apres avoir accedé a la mainframe ,je recupere les views directement dans le splitter..
    Note le controle sur la classe de base qui est valide si la classe finale dispose des macro implement_xxx

  15. #15
    Membre du Club
    Inscrit en
    Mars 2005
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 79
    Points : 46
    Points
    46
    Par défaut une rude bataille
    La bataille fut rude. De nombreux corps sans vie gisaient ça et là.

    D'autres agonisaient...

    Et puis farscape est arrivé pour sauver ceux qui pouvaient encore l'être.

    Merci à tous, le problème est résolu. :-)

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 09/09/2013, 23h03
  2. Réponses: 1
    Dernier message: 30/08/2012, 21h28
  3. Réponses: 3
    Dernier message: 03/03/2010, 11h48
  4. Récupérer un pointeur sur une classe Singleton
    Par slake13 dans le forum Débuter
    Réponses: 7
    Dernier message: 18/11/2008, 17h01
  5. [MFC] Problème pointeur sur une classe
    Par mick74 dans le forum MFC
    Réponses: 7
    Dernier message: 14/04/2004, 14h17

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