一般书中介绍的是使用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'\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;
}

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


【VS开发】使用CTabView分割多页卡窗口的更多相关文章

  1. TabLayout和ViewPager简单实现页卡的滑动

    首先需要在当前的module中的build Gradle的 dependencies中加入以下句子 compile 'com.android.support:design:23.0.1' 因为我们用到 ...

  2. 使用 AngularJS 开发一个大规模的单页应用(SPA)

      本文的目标是基于单页面应用程序开发出拥有数百页的内容,包括认证,授权,会话状态等功能,可以支持上千个用户的企业级应用. 下载源代码 介绍 (SPA)这样一个名字里面蕴含着什么呢? 如果你是经典的S ...

  3. ViewPager设置 缓存个数、页卡间距、数据更新

    在使用ViewPager常用设置 1)mViewPager.setOffscreenPageLimit(2);//设置缓存view 的个数(实际有3个,缓存2个+正在显示的1个)2)mViewPage ...

  4. android SlidingTabLayout实现ViewPager页卡滑动效果

    先来张效果图(能够滑动切换页卡) watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVuZ2t2/font/5a6L5L2T/fontsize/400/fi ...

  5. ViewPager实现页卡的3种方法(谷歌组件)

    ----方法一:---- 效果图: 须要的组件: ViewPager+PagerTabStrip 布局文件代码: <!--xmlns:android_custom="http://sc ...

  6. ViewPager实现页卡的最新方法--简洁的TabLayout(谷歌支持包)

    效果图: 添加依赖包: compile ‘com.android.support:design:‘ 布局文件: <?xml version="1.0" encoding=&q ...

  7. HorizontalScrollView做页卡的一个小记录

    用HorizontalScrollView做页卡,实现一个如下图的效果:

  8. 使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果

    在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的TabHost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使用自定义RadioButto ...

  9. Excel汇总多个页卡数据到一个页卡

    首先新建一个页卡放到最前面,页卡处右键,选择查看代码,选择需要汇总的页卡,输入以下代码,运行即可: 1.如果需要把全部数据都汇总到一个页卡 Sub 合并当前工作簿下的所有工作表() Applicati ...

随机推荐

  1. Java中的集合Queue、LinkedList、PriorityQueue(四)

    Queue接口 Queue用于模拟了队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器.队列的头部保存在队列中时间最长的元素,队列的尾部保存在队列中时间最短的元素.新元素插入(offer)到 ...

  2. 智能指针unique_ptr记录

    unique_ptr 对对象独有管理,无法复制,共享,值传递,可以使用move语义来转移控制权. std::default_delete<int> d; std::unique_ptr&l ...

  3. hybird(h5)页面自动化测试

  4. 通信网络(CCF)【图的遍历】

    问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M条通路,每条通路只能单向传递信息,即一条从部门a到部门b的通路只能由a向b传递信息.信息可以通过中转的方式进行传递,即如果a能将信息 ...

  5. @JsonIgnore等

    作用:在json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响. 使用方法:一般标记在属性或者方法上,返回的json数据即不包含该属性. 场景模拟: 需要把一个List< ...

  6. KindEditor完全复制word内容

    我司需要做一个需求,就是使用富文本编辑器时,不要以上传附件的形式上传图片,而是以复制粘贴的形式上传图片. 在网上找了一下,有一个插件支持这个功能. WordPaster 安装方式如下: 直接使用Wor ...

  7. 【转载】全网最!详!细!tarjan算法讲解。

    转自http://www.cnblogs.com/uncle-lu/p/5876729.html [转载]全网最!详!细!tarjan算法讲解.(已改正一些奥妙重重的小错误^_^) 全网最详细tarj ...

  8. bbs-admin-自定义admin(一)

    自定义admin 概要:django-admin本质就是一个app,只是Django内部分装了,因此我们尝试自己设计一个简易版的admin 设计前知识补充: model._meta.app_label ...

  9. x86—EFLAGS寄存器详解[转]

    鉴于EFLAGS寄存器的重要性,所以将这一部分内容从处理器体系结构及寻址模式一文中单独抽出另成一文,这部分内容主要来自Intel Developer Mannual,在后续的内核系列中遇到的许多和EF ...

  10. node中从express到koa再到koa2的发展历程

    koa是Express的下一代基于Node.js的web框架,目前有1.x和2.0两个版本. 历史 1. Express Express是第一代最流行的web框架,它对Node.js的http进行了封 ...