MFC学习之路(七)实现多文档的单文档多视图

来源:互联网 发布:淘宝联盟怎么注销账号 编辑:程序博客网 时间:2024/06/06 14:24
新建一个多文档应用程序假设名字为123

新建一个MFC类,派生于CView,命名为CViewTest
然后重载一个虚拟函数
void CViewTest::OnInitialUpdate()
{
CView::OnInitialUpdate();

// TODO: 在此添加专用代码和/或调用基类
GetParent()->SetWindowText(_T("测试视图"));// 设置选项卡标题
}

在应用程序类C123中创建一个公有成员变量
CMultiDocTemplate* m_pDocTemp1;

在应用程序类的源文件中添加ViewTest.h头文件
在BOOL C123::InitInstance()函数中
找到如下语句
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_My123TYPE,// 改为IDR_MAINFRAME
RUNTIME_CLASS(CMy123Doc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CMy123View));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);

然后我们把它改为
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MAINFRAME,
RUNTIME_CLASS(CMy123Doc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CMy123View));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
应为不改变IDR_My123TYPE的话,多的视图时,他会让你选择哪个文档,而实际上我们只有一个文档。

在这些语句的下方添加
m_pDocTemp1 = new CMultiDocTemplate(IDR_MAINFRAME,
RUNTIME_CLASS(CMy123Doc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CViewTest));
if (!m_pDocTemp1)
return FALSE;
AddDocTemplate(m_pDocTemp1);

然后在CMainFrame.cpp中添加ViewTest.h头文件
再添加一个函数
//创建视图
void CMainFrame::SwitchToView(CDocTemplate* pTemplate, CRuntimeClass* pViewClass)
{
//获得活动子窗口
CMDIChildWnd *pMDIActive = MDIGetActive();
if (pMDIActive == NULL) 
{
pTemplate->OpenDocumentFile(NULL);
pMDIActive = MDIGetActive();
}

//获得活动doc
CDocument *pDoc = pMDIActive->GetActiveDocument(); 
if (pDoc == NULL) 
return; 

//查询此doc下的所有已创建view
CView *pView;
POSITION pos = pDoc->GetFirstViewPosition();       
while (pos != NULL)
{
pView = pDoc->GetNextView(pos);
if (pView->IsKindOf(pViewClass))           //如果已创建此view 则设其为活动
{
//the requested view class has already been created; show it
pView->GetParentFrame()->ActivateFrame();  

pView->UpdateWindow();//视图更新显示;
pView->Invalidate();  //再刷新才可以
return;
}
}

//如果没有创建,则创建此view的childframe及view
CMDIChildWnd *pNewFrame = (CMDIChildWnd *)pTemplate->CreateNewFrame(pDoc, NULL);  
if (pNewFrame == NULL)
return;

pTemplate->InitialUpdateFrame(pNewFrame, pDoc);
}

再在IDR_MAINFRAME下添加一个菜单,假设菜单ID为ID_TEST,添加消息响应

void CMainFrame::OnTest()
{
// TODO: 在此添加命令处理程序代码
SwitchToView(theApp.m_pDocTemp1, RUNTIME_CLASS(CViewTest));
}

新选项卡弹出来了,可是标题没变,咋办?
在CChildFrm类的虚函数BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs);
中添加cs.style &=~(LONG)FWS_ADDTOTITLE;  他去除了自动添加窗口标题,这样我们就可以自由修改啦!