一、SDI
1、into mainframe.h add member
int m_currentView;
CView2* m_pView2;
CView1* m_pView1;
2、in InitInstance()
((CMainFrame*)m_pMainWnd)->m_pView1=(CView1*)(((CMainFrame*)m_pMainWnd)->GetActiveView());
3、add message handler
in head file
afx_msg void OnViewChange(UINT nCmdID);
in cpp file
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_COMMAND_RANGE(IDM_VIEW1,IDM_VIEW2, OnViewChange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
m_pView2=NULL;
m_currentView=1;
}
void CMainFrame::OnViewChange(UINT nCmdID)
{
// TODO: Add your command handler code here
CView* pViewAdd;
CView* pViewRemove;
CDocument* pDoc = GetActiveDocument();
if((nCmdID == IDM_VIEW1) && (m_currentView == 1))
return;
if((nCmdID == IDM_VIEW2) && (m_currentView == 2))
return;
if (nCmdID == IDM_VIEW2)
{
if (m_pView2 == NULL)
{
m_pView1 = (CView1*)GetActiveView();
m_pView2 = new CView2;
// If OnSize has been overridden in CMyView2
// and GetDocument() is used in this override it can
// cause assertions and, if the assertions are ignored,
// cause access violations.
m_pView2->MyCreate(NULL, NULL, AFX_WS_DEFAULT_VIEW,
rectDefault, this, AFX_IDW_PANE_FIRST + 1, NULL);
}
pViewAdd = m_pView2;
pViewRemove = m_pView1;
m_currentView= 2;
}
else
{
pViewAdd = m_pView1;
pViewRemove = m_pView2;
m_currentView= 1;
}
// Set the child identifier of the active view to AFX_IDW_PANE_FIRST,
// so that CFrameWnd::RecalcLayout will allocate to this
// first pane, that portion in a client area of the frame window that is
// not allocated to control bars. Set the child identifier of the
// other view to anything besides AFX_IDW_PANE_FIRST; this
// example switches the child identifiers of the two views.
int nSwitchChildID = pViewAdd->GetDlgCtrlID();
pViewAdd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pViewRemove->SetDlgCtrlID(nSwitchChildID);
// Show the newly active view and hide the inactive view.
pViewAdd->ShowWindow(SW_SHOW);
pViewRemove->ShowWindow(SW_HIDE);
// Connect the newly active view to the document and
// disconnect the inactive view.
pDoc->AddView(pViewAdd);
pDoc->RemoveView(pViewRemove);
SetActiveView(pViewAdd);
RecalcLayout();
}
void CView2::MyCreate(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
CFormView::Create(lpszClassName, lpszWindowName, dwStyle,
rect, pParentWnd, nID, pContext);
}
Don not fetget edit menu resource。
I make mfc sdi project by default setting, in step 6 CView1 derived from CFormView
and insert dialog with child , border none style,then add CView2 into project。
二、MDI
is similarly with sdi
the replaceview() function u could found in msdn but not the same
I don not destroy view and recreate view.
now i ctr+v the core code
mainframe.cpp
BOOL CMainFrame::ReplaceView(CView* pNewView )
{
CMDIFrameWnd* pMainWnd = (CMDIFrameWnd*)AfxGetMainWnd();
// Get the active MDI child window.
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainWnd->MDIGetActive();
// Get the active view attached to the active MDI child window.
CView* pOldActiveView = pChild->GetActiveView();
// Set flag so that document will not be deleted when view is dettached.
CDocument * pDoc= pOldActiveView->GetDocument();
BOOL bAutoDelete=pDoc->m_bAutoDelete;
pDoc->m_bAutoDelete = FALSE;
// Dettach existing view
pDoc->RemoveView(pOldActiveView);
// restore flag
pDoc->m_bAutoDelete = bAutoDelete;
// Show the newly active view and hide the inactive view.
pNewView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
// Attach new view
pDoc->AddView(pNewView);
pChild->RecalcLayout();
pNewView->UpdateWindow();
pChild->SetActiveView(pNewView);
return true;
}
void CMainFrame::OnViewChange(UINT nID)
{
// TODO: Add your command handler code here
switch( nID)
{
case IDM_VIEW1:
ReplaceView(m_pView1);
break;
case IDM_VIEW2:
CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
// Get the active MDI child window.
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainWnd->MDIGetActive();
if (!m_pView2)
{
// create the new view
m_pView2 = new CView2;
m_pView2->MyCreate(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0),
pChild, AFX_IDW_PANE_FIRST, NULL);
}