VC单文档切分动态更换多视图代码分析
带切分的主要的函数有2个,一个是建立时候的函数,一个是切换的函数,两个基本上很类似,这里分析一下切换的函数:
void CMainFrame::OnSwitchView1()
{
// TODO: Add your command handler code here
CRect cr;
GetClientRect(&cr);//取得客户区的显示区域
CSize paneSize1(3*cr.Width()/4, cr.Height());//设定新view大小
CCreateContext Context;//声明视图文档联系结构并设定其内容
Context.m_pNewViewClass=RUNTIME_CLASS(CSwitchView1);
Context.m_pCurrentDoc=((CSwitchApp*)AfxGetApp())->m_pDoc;
Context.m_pCurrentFrame=this;
Context.m_pNewDocTemplate=Context.m_pCurrentDoc->GetDocTemplate();
Context.m_pLastView=(CView*)m_wndSplitter.GetPane(0,0);
m_wndSplitter.DeleteView(0, 1);//删除第1行第2列的View
m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CSwitchView1),paneSize1, &Context);//动态创建View1
CSwitchView1 *pView=(CSwitchView1*)m_wndSplitter.GetPane(0,1);//得到切分窗口的指针
pView->GetParentFrame()->RecalcLayout();//重绘主窗口
m_wndSplitter.RecalcLayout();//重绘分隔条窗口
pView->OnInitialUpdate();//估计是一些初始化的操作
m_wndSplitter.SetActivePane(0,1);//激活新的分隔区域
}
不带切分的代码如下:
void CMainFrame::SwitchToView(int nForm)
{
//CDocument* pDoc = GetActiveDocument();
CView *pOldActiveView=GetActiveView(); //保存旧视图
CView *pNewActiveView=(CView*)GetDlgItem(nForm); //取得新视图
if(pNewActiveView==NULL)
{
switch(nForm)
//这些ID是对话框的标志符,但也可以用其他的标志
{
case IDD_DIALOG1 :
pNewActiveView=(CView*)new TForm;
break;
case IDD_FORMVIEW :
pNewActiveView=(CView*)new TForm2;
break;
}
CCreateContext context; //将文挡和视图相连
context.m_pCurrentDoc=pOldActiveView->GetDocument();
pNewActiveView->Create(NULL, NULL, WS_BORDER|WS_CHILD ,
CFrameWnd::rectDefault, this, nForm, &context);
pNewActiveView->OnInitialUpdate();
}
SetActiveView(pNewActiveView); //改变活动的视图
pNewActiveView->ShowWindow(SW_SHOW); //显示新的视图
pOldActiveView->ShowWindow(SW_HIDE); //隐藏旧的视图
if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(TForm))
pOldActiveView->SetDlgCtrlID(IDD_DIALOG1);
else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(TForm2))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
delete pOldActiveView; //删除旧视图
RecalcLayout(); //调整框架窗口
}
比对一下可以看出,带切分的主要是通过m_wndSplitter这样一个成员进行操作,而不带切分的则是直接对整个View进行操作。(因为没有m_wndSplitter啊,呵呵。)
补充:
void CMainFrame::OnSwitchView1()
{
m_wndSplitter.DeleteView(1, 0);
m_wndSplitter.CreateView(1, 0,
RUNTIME_CLASS(TForm2),
CSize(0, 0),
NULL);
m_wndSplitter.RecalcLayout();
}