SDI ohne Doc/View splitten



  • So, jetzt nochmal richtig:

    Um eine SDI-Anwendung OHNE Doc/View-Unterstützung in 2 Wnds zu splitten, kann man NICHT genauso vorgehen wie bei einer Anwendung MIT Doc/View. Schreibt man
    hier seinen Split-Code in die Methode OnCreateClient(), so werden die Statusleiste und die Symbolleiste gesplittet, der MainFrame jedoch nicht. Daher muss man seinen Code umschreiben:

    1. Man legt eine CSplitterWnd-Member-Variable in der Klasse CMainFrame an:

    // Attribute
    public:
       CSplitterWnd m_pSplitterWnd;
    

    2. Nun müssen wir so viele Klassen von CView-Klassen ableiten, wie wir später Panes (also Teilfenster) haben wollen. In diesem Beispiel sollen's 2 sein:
    Einmal eine von CTreeView abgeleitet, einmal eine von CListView. Die View-Klassen sind dabei Äquivalente zu den Klassen CTreeCtrl und CListCtrl. Aber dazu später. Wir nehmen also den Klassen-Assistenten und leiten die beiden Klassen ab, hier heißen sie dann:

    CTreeView --> CTree
    CListView --> CList
    

    3. Wir includieren die Header-Dateien dieser beiden Klassen in MainFrm.cpp:

    #include "Tree.h"
    #include "List.h"
    

    4. Nun schreiben wir in die CMainFrame-Methode ganz am Ende den Code zum Splitten:

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
       //Statusleisten etc. erstellen
    
       if(!m_pSplitterWnd.CreateStatic(this, 1, 2))
       {
          TRACE0("Failed to create splitter bar ");
          return FALSE;    //Fehler beim Createn
       }
    
       m_pSplitterWnd.CreateView(0, 0, RUNTIME_CLASS(CTree), CSize(175,100), NULL);
       m_pSplitterWnd.CreateView(0, 1, RUNTIME_CLASS(CList), CSize(500,100), NULL);
    
       return 0;
    }
    

    Hier wird der MainFrame vertikal in 2 Panes gesplittet. Der linke Teil bekommt als View-Klasse CTree, der rechte CTree.

    5. Nun müssen die View-Klassen (CTree & CList) noch initialisiert werden. Wir wollen nur kurz als Beispiel die List-View in 4 Spalten unterteilen. Dazu fügen wir dieser Klasse eine Antwort-Methode auf die Message WM_CREATE hinzu und fügen dort folgenden Code ein:

    int CList::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
       if(CListView::OnCreate(lpCreateStruct) == -1)
          return -1;
    
       //wir holen uns ein CListCtrl-Objekt, um damit arbeiten zu können
       CListCtrl& lc = GetListCtrl();
    
       lc.ModifyStyle(0, LVS_REPORT); //optional
    
       lc.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); //optional
    
       lc.InsertColumn(0, _T("Spalte 1"), LVCFMT_LEFT);
       lc.InsertColumn(1, _T("Spalte 2"), LVCFMT_LEFT);
       lc.InsertColumn(2, _T("Spalte 3"), LVCFMT_LEFT);
       lc.InsertColumn(3, _T("Spalte 4"), LVCFMT_LEFT);
    
       lc.SetColumnWidth(0,150);
       lc.SetColumnWidth(1,170);
       lc.SetColumnWidth(2,130);
       lc.SetColumnWidth(3,200);
    
       return 0;
    }
    

    Wir dürfen das alles nicht in die OnInitialUpdate-Methode der View-Klasse schreiben, da diese 2x aufgerufen wird. Das hat - "Called by the framework after the view is first attached to the document" - was mit der Doc/View-Unterstützung zu tun: Wir haben aber keine.

    So, das war's schon. Hoffe, diesmal ist nix schiefgegangen.

    MfG

    Happosai

    -- Style korrigiert --

    [ Dieser Beitrag wurde am 21.02.2003 um 13:32 Uhr von Happosai editiert. ]


Anmelden zum Antworten