在一些情況下,應(yīng)用程序有許多信息要顯示,當(dāng)一個(gè)窗口內(nèi)顯示不下時(shí),VC提供的MDI應(yīng)用程序可以解決這個(gè)問(wèn)題,但是如果應(yīng)用程序只是對(duì)單
個(gè)文檔,采用多種方式顯示,則采用SDI更合適。那么,如何在單文檔應(yīng)用程序中實(shí)現(xiàn)多視圖呢?缺省情況下,派生類的構(gòu)造函數(shù)是pretected類型的,
必須將它改為public類型,因?yàn)槲覀儗?huì)動(dòng)態(tài)生成派生視圖類并切換活動(dòng)的視圖。也可以一次生成所有的視圖,但是這樣造成系統(tǒng)資源的極大浪費(fèi)。
1 首先利用資源編輯器新建4個(gè)對(duì)話框,在對(duì)話框中添加需要的控件,各個(gè)對(duì)話框的ID分別為IDD_MULTIVIEW_FORM,IDD_MULTIVIEW_FORM2,IDD_MULTIVIEW_FORM3,IDD_MULTIVIEW_FORM4
2 為每一個(gè)對(duì)話框創(chuàng)建一個(gè)CFormView類的派生類,分別為:CView1,CView2,CView3,CView4
3 在應(yīng)用程序的初始化文件中用CView1替換原先的視圖,這樣程序啟動(dòng)后的缺省顯示視圖是CView1,修改后的部分代碼如下:
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CView1));
AddDocTemplate(pDocTemplate);
4 利用資源編輯器,添加幾個(gè)菜單,并添加相應(yīng)的消息處理函數(shù):
void CMainFrame::OnViewView1()
{
SwitchToForm(IDD_MULTIVIEW_FORM);
}
void CMainFrame::OnViewView2()
{
SwitchToForm(IDD_MULTIVIEW_FORM2);
}
void CMainFrame::OnViewView3()
{
SwitchToForm(IDD_MULTIVIEW_FORM3);
}
void CMainFrame::OnViewView4()
{
SwitchToForm(IDD_MULTIVIEW_FORM4);
}
在
SDI中CFrame的派生類即CMainFrame控制著所有的視圖,而且它允許用戶通過(guò)消息處理進(jìn)行視圖的切換。進(jìn)行視圖切換的原理很簡(jiǎn)單,只是斷開(kāi)
和舊視圖的連接并把他刪除,創(chuàng)建一個(gè)新視圖,將文檔和它相連,設(shè)置幾個(gè)標(biāo)志,然后顯示新視圖,SwitchToForm函數(shù)是進(jìn)行視圖切換的代碼函數(shù)。
void CMainFrame::SwitchToForm(int nForm)
{
//CDocument* pDoc = GetActiveDocument();
CView *pOldActiveView=GetActiveView(); //保存舊視圖
CView *pNewActiveView=(CView*)GetDlgItem(nForm); //取得新視圖
if(pNewActiveView==NULL)
{
switch(nForm)
//這些ID是對(duì)話框的標(biāo)志符,但也可以用其他的標(biāo)志
{
case IDD_MULTIVIEW_FORM :
pNewActiveView=(CView*)new CView1;
break;
case IDD_MULTIVIEW_FORM2 :
pNewActiveView=(CView*)new CView2;
break;
case IDD_MULTIVIEW_FORM3 :
pNewActiveView=(CView*)new CView3;
break;
case IDD_MULTIVIEW_FORM4 :
pNewActiveView=(CView*)new CView4;
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); //改變活動(dòng)的視圖
pNewActiveView->ShowWindow(SW_SHOW); //顯示新的視圖
pOldActiveView->ShowWindow(SW_HIDE); //隱藏舊的視圖
if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView1))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM);
else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView2))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM2);
else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView3))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM3);
else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView4))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM4);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
delete pOldActiveView; //刪除舊視圖
RecalcLayout(); //調(diào)整框架窗口
}