Ansichtsklasse + Zugriff + SDI



  • Hallo,

    wie kann ich in einer SDI Anwendung in einem Dialogfeld auf die Ansichtsklasse zugreifen wenn diese nicht das Elternfenster ist ?

    Ist es möglich irgendwie über die Rahmenfensterklasse ( CMainFrame ) auf die Ansichtsklasse zuzugreifen ?

    Vielen dank schonmal



  • Eigentlich solltest du das in der CDocument-Klasse machen. Besser noch du machst alle CView spezifischen Sachen in der CView-Klasse. Die Windows Architektur sieht vor, in der CView-Klasse Zugriff auf die Documentdaten zu haben. Anders ist es unsauber.

    Siehe: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_Frame_Window_Topics.asp

    codeman



  • Hi,
    schön, das auch andere diese Probleme haben, mit denen ich mich auch schon ewig rumgeschlagen habe...
    Das Thema Pointer auf View oder Document hab ich auch noch nicht ganz durchschaut, das Problem ist, das beide Klassen Runtime_Classes sind.
    Folgender Link könnte dir helfen:

    http://www.codeguru.com/forum/showthread.php?t=281430

    Oh, halt Stop! Kein Kindfenster von CView... Dann geht das wahrscheinlich nicht,
    aber folgendes sollte gehen:

    1. Erstelle dir mittels new als Membervariable in deinem Dialog einen Pointer auf die Klasse CVIEW (NICHT deine View, sondern die Elternklasse)
    2. Schreibe in deinem Dialog eine public Set-Methode, die einen Pointer vom Typ CView bekommt.
    3. Führe diese Set-Methode aus der View heraus aus (Voraussetzung ist ein Poiner auf deinen Dialog, weiß ich nicht, ob du den hast), nachdemn dein Dialog geöffnet ist und übergebe ihr die Adresse deiner View. Damit hast du einen Pointer auf die Klasse CView in deinem Dialog.
    4. An der Stelle, wo es nötig ist, caste diesen CView-Pointer auf deine View um und du hast Zugriff auf die View...

    Warum das ganze rumgecaste? Ich hab es nicht geschafft, direkt einen Pointer vom Typ meiner View irgendwo als Klassenvariable anzulegen. Lokal innerhalb einer Methode funktioniert dies aber einwandfrei. Mit derselben Vorgehensweise kriegt man auch einen Pointer auf die Dok.

    Das ist die einzige (wahrscheinlich eher suboptimale) Methode, wie ich das hinbekommen habe, über die MainFrame und ähnliche Spiele (siehe Link) scheinen nur bei direkten Kindklassen zu funktionieren.

    Falls jemand ne bessere, einfachere Methode hat, die nicht so von hinten durch die Brust direkt ins Auge geht, hätte ich auch großes Interesse. 😃

    Grüße Squeegee



  • Gibt noch die Möglichkeit, in deiner CDocument-Klasse einen Pointer von CView oder einer davon abgeleiteten Klasse(CScrollView, etc.) an zu legen. Dann in der Methode IntitialUpdate der CView-Klasse einfach mit GetDocument einen Pointer auf die CDocument-Klasse holen und den "this" Zeiger in dem CView-Pointer in der CDocument-Klasse speichern.

    Nun hast du ihn in der CDocumenten-Klasse die jederzeit erreichbar ist. Wenn es mehrere CView's sind, einfachen ein Array von CViews in der CDocumenten-Klasse anlegen. Und fertig ist die Marie. 😉

    codeman



  • Hi Codeman,
    wie schaffst du es denn, in der Dokumentenklasse einen Pointer vom Typ deiner View anzulegen? Das geht bei mir halt nie?!? Beispiel:

    ViewKlasse: CMyView
    Anlegen eines eines Pointers in der Dok: CMyView *pMyView;
    Klappt net, weil unbekannt, also inlcude ich in der Dok MyView.h
    Jetzt bekomm ich ca. 30 Fehler verschiedenster Art und Weise, die gar nix mit meinem Problem zu tun haben... 😃

    Und noch ne Frage:

    Nun hast du ihn in der CDocumenten-Klasse die jederzeit erreichbar ist

    Wieso ist die Dokumentenklasse jederzeit erreichbar? Doch nur aus der/den View/s über GetDocument, oder? Hilft das bei einem Dialog, der ja, wie XeXeS schreibt, gar kein Kind von der View ist?

    Ich glaub, ich hab da irgendwo generell was noch net so ganz verstanden 😡

    Grüße Squeegee



  • Hi !

    Ich erklär vieleicht mal noch genaure was ich machen will. Ich habe eine von CDialog abgeleitete Klasse welche ich als Kindfenster in einer Art Toolbar anzeigen lassen. Diese Toolbar ist aber wie jede andere ToolBar auch ein Kindfenster von CMainFrame. Das Problem ist das ich in der Dialogklasse einen Zeiger auf das Fenster der Viewklasse brauche. Der Grunddafür ist das ich einen zweiten Thread starten will welcher nachrichten zur Viewklasse sendet um das Fenster neu zu zeichnen.

    Mein Problem ist das ich die nachricht WM_PAINT zwar an das Fenster CMainFrame senden kann was kein Problem ist aber ich kann es nicht an die View setzen.

    Die Lösung die möglich wäre ist einen globalen zeiger in der OnCreate des Views zu initialisieren. Dann hätte ich das was ich brauche aber ich denke nicht das das der Weg ist den man gehen sollte.

    Mit freundlichem Gruß
    S. Leopold



  • Ich hab das Problem gelöst wenn man das mal so sagen darf.

    Da man zu jeder zeit von überall zugriff auf das Objekt der Rahmenklasse hat kann man auch Überall auf den View und das zugehörige Dokument zugreifen.

    Hier mal der Code mit Comments:

    SDI:

    // Zuerst zeiger auf die Rahmenklasse
    CMainFrame* pFrame = (CMainFrame*)::AfxGetApp()->m_pMainWnd;
    
    // Um einen Zeiger auf den View zu erhalten (SDI)
    CMyView* pView = (CMyView*)pFrame->GetActiveView();
    
    // Um einen Zeiger auf das Dokument zu erhaltne (SDI)
    CMyDoc* pDoc = (CMyDoc*)pFrame->GetActiveView()->GetDocument();
    

    MDI:

    // Zuerst zeiger auf die Rahmenklasse
    CMainFrame* pFrame = (CMainFrame*)::AfxGetApp()->m_pMainWnd;
    
    // Um einen Zeiger auf den View zu erhalten (MDI)
    CMyView* pView = (CMyView*)pFrame->MDIGetActive()->GetActiveView();
    
    // Um einen Zeiger auf das Dokument zu erhaltne (MDI)
    CMyDoc* pDoc = (CMyDoc*)pFrame->MDIGetActive()->GetActiveView()->GetDocument();
    

    Vieleicht klärt das einiges.


Anmelden zum Antworten