在MFC的SDI和MDI文档结构中能很方便的嵌入多视图,而有时候则要在对
话框中嵌入多视图,下面是方法。
插入三个对话框,ID分别为IDD_VIEW1_FORM,IDD_VIEW2_FORM,IDD_VIEW3_FORM
把三个对话框的属性Style设为Child,Border设为None,映射
CView1,CView2,CView3分别对应三个对话框,CView1,CView2,CView3都派生自CFormView。
在对话框中加入三个成员变量:
1 CView1 *m_pView1;
2 CView2 *m_pView2;
3 CView3 *m_pView3;
映射对话框WM_INITDIALOG消息,在OnInitDialog()函数中加入创建视图窗口的代码。
(注意一定要用(CView*)把三个成员变量的类型转换成CView*类型,不然调用的就是CFormView::Create,但是CFromView的Create是protected类型,不能调用)
//create view1 m_pView1 = new CView1; ASSERT(m_pView1 != NULL); if (!((CView*)m_pView1)->Create(NULL, NULL, WS_CHILD, CRect(0, 0, 0, 0), this, NULL, NULL)) { AfxMessageBox(_T("Create view1 failed")); return TRUE; } m_pView1->ShowWindow(SW_HIDE); m_pView1->OnInitialUpdate(); //create view2 m_pView2 = new CView2; ASSERT(m_pView2 != NULL); if (!((CView*)m_pView2)->Create(NULL, NULL, WS_CHILD, CRect(0, 0, 0, 0), this, NULL, NULL)) { AfxMessageBox(_T("Create view2 failed")); return TRUE; } m_pView2->ShowWindow(SW_HIDE); m_pView2->OnInitialUpdate(); //create view3 m_pView3 = new CView3; ASSERT(m_pView3 != NULL); if (!((CView*)m_pView3)->Create(NULL, NULL, WS_CHILD, CRect(0, 0, 0, 0), this, NULL, NULL)) { AfxMessageBox(_T("Create view3 failed")); return TRUE; } m_pView3->ShowWindow(SW_HIDE); m_pView3->OnInitialUpdate(); //move view in the dialog CRect rect; GetWindowRect(&rect); ScreenToClient(rect); rect.DeflateRect(200, 0, 0, 0); m_pView1->MoveWindow(&rect); m_pView2->MoveWindow(&rect); m_pView3->MoveWindow(&rect); ((CFrameWnd*)this)->SetActiveView(m_pView1); m_pView1->ShowWindow(SW_SHOW); m_pView1->SetDlgCtrlID(AFX_IDW_PANE_FIRST); ......
在对话框中按顺序加入三个radio box,在第一个radio box中勾上group选项(三个radio box 靠左边放,注意不要被嵌入的视图覆盖住。
。在映射按钮消息函数中加入SwitchToView函数。(SwitchToView用来切换视图)
void Cxxxxx::OnRadio1()
{
SwitchToView(IDD_VIEW1_FORM);
}
void Cxxxxx::OnRadio2()
{
SwitchToView(IDD_VIEW2_FORM);
}
void Cxxxxx::OnRadio3()
{
SwitchToView(IDD_VIEW3_FORM);
}
SwitchToView的函数定义为:
void Cxxxxx::SwitchToView(UINT uViewID)
{
//the following statement is important!!!
CFrameWnd *pFrame = (CFrameWnd*)this;
//only for debug
ASSERT_VALID(pFrame);
CView *pNewActiveView = NULL;
CView* pOldActiveView = (CView*)pFrame->GetActiveView();
switch(uViewID)
{
case IDD_VIEW1_FORM:
pNewActiveView = m_pView1;
break;
case IDD_VIEW2_FORM:
pNewActiveView = m_pView2;
break;
case IDD_VIEW3_FORM:
pNewActiveView = m_pView3;
break;
default:
AfxMessageBox(_T("invalid view id"));
return;
}
ASSERT(pOldActiveView!=NULL && pNewActiveView!=NULL);
if (pNewActiveView == pOldActiveView)
return;
pNewActiveView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
pFrame->SetActiveView(pNewActiveView);
if (pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView1)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW1_FORM);
else if(pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView2)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW2_FORM);
else if (pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView3)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW3_FORM);
//set the identity of current active view
pNewActiveView -> SetDlgCtrlID(AFX_IDW_PANE_FIRST);
}