zoukankan      html  css  js  c++  java
  • 【VS开发】使用CTabView分割多页卡窗口

    一般书中介绍的是使用CSplitterWnd来拆分窗口实现多视图,CSplitterWnd中的CreateClient可以保存其创建的pCreateContext指针,以便子视图共享Document。这我用一篇文章详细说明。CTabView建立多视图的好处在于简单的标签切换,可以让每个View的窗口都很大。下面说说如何操作:

    在建立项目时,程序向导最后一步并未提供让View为CTabView类型,因此我们需要自己新建一个CTabView的子类。

    在vc2008中,在项目菜单中“项目”->“添加类”,可以自动生成类,像vc6的话ClassWizard也可以自动添加。

    修改WinApp中的InitInstance中的new CMultiDocTemplate(),修改其中的View类型为刚刚新建的CTabView子类。

    复制代码
        // 注册应用程序的文档模板。文档模板
        // 将用作文档、框架窗口和视图之间的连接
        CMultiDocTemplate* pDocTemplate;
        pDocTemplate = new CMultiDocTemplate(IDR_TestTabViewTYPE,
            RUNTIME_CLASS(CTestTabViewDoc),
            RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
            RUNTIME_CLASS(CMyTabView));
        if (!pDocTemplate)
            return FALSE;
        AddDocTemplate(pDocTemplate);
    复制代码

    修改完成后,可以看出TabView的形态已经出来了,不过里面没有子View。下面来添加子view。

    一般子view也需要新建,继续使用自动新建类,可以建立CFormView、ClistView等等的视图来显示数据。

    新建子view在CTabView的OnCreate函数中,在新建类中需要新建CCreateContext来将Doc给新的View。

    复制代码
    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;
    }
    复制代码

    上述代码新建了2个视图,CCreateContext指定需要新建View,指定Doc为TabView的Doc,在AddView中的最后参数中将CCreateContext传入。

    至此,子视图中可以使用GetDocument来得到在WinApp中CTestTabViewDoc的类实例指针,这些子视图共享了同一份Doc。

     

    后续:

    过了几天,我无意间发现AddView的代码,是自动将自己的Doc传给子tab,请看代码:

    复制代码
    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'
    ", 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;
    }
    复制代码

    所以,只要AddView就可以,不再需要CCreateContext结构体作为参数,子tab就可以获得Doc指针了。


  • 相关阅读:
    DataGrid( 数据表格) 组件[2]
    DataGrid( 数据表格) 组件[1]
    Form( 表单) 组件
    Slider( 滑动条) 组件
    内存管理-常见内存泄露-(5)
    Android 内存管理分析(四)
    Android 之 内存管理-查看内存泄露(三)
    Android 内存管理(二)
    正确认识Android的内存管理机制,合理关闭进程 (一)
    谈谈Runtime类中的freeMemory,totalMemory,maxMemory等几个方法
  • 原文地址:https://www.cnblogs.com/huty/p/8518679.html
Copyright © 2011-2022 走看看