谁说过一个框架窗口在整个生存期内都应该受其关联的视图的束缚呢?在用户接口中增加某些魔法,让用户动态的选中它们想要放进同一个框架窗口内的视图,使用EkSwitchViewInFrame()公用函数,切换视图只是一个函数调用的问题。
第1步:实现EkSwitchViewInFrame()函数,该函数通过 动态的 创建 所需要的 视图类型 而 替换 框架窗口内 的 当前视图。
- void EkSwitchViewInFrame(CFrameWnd* pFrame,CRuntimeClass* pViewClass)
- {
- ASSERT_VALID(pFrame);
- ASSERT(pViewClass!=NULL);
- ASSERT(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));
- //1、查找当前的活动视图
- CView *pActiveView=pFrame->GetActiveView();
- if(pActiveView == NULL)
- {
- TRACE0("Unable to switch:no active view/n");
- return ;
- }
- if(pActiveView->IsKindOf(pViewClass))
- {
- //对同一个视图类不需切换
- return;
- }
- //2、保存当前视图的位置大小
- CRect rcView;
- pActiveView->GetWindowRect(&rcView);
- //3、查找关联的文档
- CDocument* pDoc=pActiveView->GetDocument();
- ASSERT_VALID(pDoc);
- //4、当释放活动视图时,确保文档不会自我析构
- BOOL bSaveAutoDelete = pDoc->m_bAutoDelete;
- pDoc->m_bAutoDelete=false;
- //5、释放活动视图
- pActiveView->DestroyWindow();
- //6、恢复文档到初始状态
- pDoc->m_bAutoDelete=bSaveAutoDelete ;
- //7、初始化CreateView()使用的创建上下文
- CCreateContext context;
- context.m_pNewDocTemplate=NULL;
- context.m_pLastView=NULL;
- context.m_pCurrentFrame=NULL;
- context.m_pNewViewClass=pViewClass;
- context.m_pCurrentDoc=pDoc;
- //8、创建新的视图
- CView* pNewView=static_cast<CView*>(pFrame->CreateView(&context));
- ASSERT(pNewView);
- //9、定位新视图,与旧视图位置相同
- pFrame->ScreenToClient(&rcView);
- pNewView->MoveWindow(&rcView,true);
- //10、给视图发送WM_INITIALUPDATE消息
- pFrame->InitialUpdateFrame(pDoc,true);
- }
第2步:当打算在某个特定的框架窗口内切换一个新视图时,调用EkSwitchViewInFrame()函数。
- #include "DrawView.h"
- #include "DrawFormView.h"
- void CDrawDoc::OnSwitchDrawView()
- {
- CFrameWnd* pActiveFrame = EkGetActiveFrame();
- if( pActiveFrame )
- {
- EkSwitchViewInFrame(pActiveFrame,RUNTIME_CLASS( CDrawView ) );
- }
- }
- void CDrawDoc::OnSwitchFormView()
- {
- CFrameWnd* pActiveFrame = EkGetActiveFrame();
- if( pActiveFrame )
- {
- EkSwitchViewInFrame(pActiveFrame,RUNTIME_CLASS( CDrawFormView ) );
- }
- }