天天看點

【VS開發】使用CTabView分割多頁卡視窗

一般書中介紹的是使用CSplitterWnd來拆分視窗實作多視圖,CSplitterWnd中的CreateClient可以儲存其建立的pCreateContext指針,以便子視圖共享Document。這我用一篇文章詳細說明。CTabView建立多視圖的好處在于簡單的标簽切換,可以讓每個View的視窗都很大。下面說說如何操作:

在建立項目時,程式向導最後一步并未提供讓View為CTabView類型,是以我們需要自己建立一個CTabView的子類。

在vc2008中,在項目菜單中“項目”->“添加類”,可以自動生成類,像vc6的話ClassWizard也可以自動添加。

修改WinApp中的InitInstance中的new CMultiDocTemplate(),修改其中的View類型為剛剛建立的CTabView子類。

【VS開發】使用CTabView分割多頁卡視窗

// 注冊應用程式的文檔模闆。文檔模闆
    // 将用作文檔、架構視窗和視圖之間的連接配接
    CMultiDocTemplate* pDocTemplate;
    pDocTemplate = new CMultiDocTemplate(IDR_TestTabViewTYPE,
        RUNTIME_CLASS(CTestTabViewDoc),
        RUNTIME_CLASS(CChildFrame), // 自定義 MDI 子架構
        RUNTIME_CLASS(CMyTabView));
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);      
【VS開發】使用CTabView分割多頁卡視窗

修改完成後,可以看出TabView的形态已經出來了,不過裡面沒有子View。下面來添加子view。

一般子view也需要建立,繼續使用自動建立類,可以建立CFormView、ClistView等等的視圖來顯示資料。

建立子view在CTabView的OnCreate函數中,在建立類中需要建立CCreateContext來将Doc給新的View。

【VS開發】使用CTabView分割多頁卡視窗
int CMyTabView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CTabView::OnCreate(lpCreateStruct) == -1)
        return -1;
    // TODO:  在此添加您專用的建立代碼
    CCreateContext context;
    context.m_pNewViewClass = RUNTIME_CLASS(CView1);
    context.m_pCurrentDoc = GetDocument();

    AddView(RUNTIME_CLASS(CView1),"哈哈",100,&context);
    context.m_pNewViewClass = RUNTIME_CLASS(CEditView);
    AddView(RUNTIME_CLASS(CEditView),"呵呵",101,&context);

    return 0;
}      
【VS開發】使用CTabView分割多頁卡視窗

上述代碼建立了2個視圖,CCreateContext指定需要建立View,指定Doc為TabView的Doc,在AddView中的最後參數中将CCreateContext傳入。

至此,子視圖中可以使用GetDocument來得到在WinApp中CTestTabViewDoc的類執行個體指針,這些子視圖共享了同一份Doc。

【VS開發】使用CTabView分割多頁卡視窗
int CTabView::AddView(CRuntimeClass* pViewClass, const CString& strViewLabel, int iIndex /*= -1*/, CCreateContext* pContext/* = NULL*/)
{
    ASSERT_VALID(this);
    ENSURE(pViewClass != NULL);
    ENSURE(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));

    CView* pView = DYNAMIC_DOWNCAST(CView, pViewClass->CreateObject());
    ASSERT_VALID(pView);

    if (!pView->Create(NULL, _T(""), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), &m_wndTabs, (UINT) -1, pContext))
    {
        TRACE1("CTabView:Failed to create view '%s'\n", pViewClass->m_lpszClassName);
        return -1;
    }

    CDocument* pDoc = GetDocument();
    if (pDoc != NULL)
    {
        ASSERT_VALID(pDoc);

        BOOL bFound = FALSE;
        for (POSITION pos = pDoc->GetFirstViewPosition(); !bFound && pos != NULL;)
        {
            if (pDoc->GetNextView(pos) == pView)
            {
                bFound = TRUE;
            }
        }

        if (!bFound)
        {
            pDoc->AddView(pView);
        }
    }

    m_wndTabs.InsertTab(pView, strViewLabel, iIndex);

    int nTabs = m_wndTabs.GetTabsNum();
    return nTabs - 1;
}      
【VS開發】使用CTabView分割多頁卡視窗