【交互】MFC单文档多视图实例分析
2013-10-30 18:01
218 查看
一、基本原理
对于多文档App而言,首先是创建CMainFrame窗口和它的子窗口MDIClient。当新建一个文档,则会new CDocument,顺便创建CChildFrame和它的子窗口CView,再次新建时,会建立另一个文档,创建另外一个CChildFrame和它的子窗口CView。对于不同视图,CView的ID标识是AFX_IDW_PANE_FIRST。在本次CChildFrame新建另外的CView时,ID标识要改变,以免重复。
向MDIClient发送WM_MDICREATE创建CChildFrame时,内部会分配子窗口的ID值,另外MDIClient在CManiFrame::OnCreate中调用到CMDIFrameWnd中的一个函数,里面创建时,Menu ID标识也是AFX_IDW_PANE_FIRST,但是MDIClient的创建 CLIENTCREATESTRUCT ccs的里面,可以指定子窗口id标识ccs.id,即子窗口CChildFrame的id标识从这个数字开始编号AFX_IDM_FIRST_MDICHILD。
若要获取激活窗口,则向MDIClient发送WM_GETACTIVATE消息,每个激活的CChildFrame父类CFrameWnd保存一个 CView* m_pViewActive,也就是CChildFrame会有一个主视图。
二、SDI单文档多视图的实现及自由切换【1、2】
主要是获取当前活动文档ActiveDocument,放到context.m_pCurrentDoc,然后再创建的时候,传上下文context信息。
classCMultiViewApp : publicCWinApp{
public:
CView* m_pFirstView;
CView* m_pOtherView;
int m_currentView;
CView* m_pView2;
CView* m_pView1;
}
CMultiViewApp::InitInstance()
{
CDocument* pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
//通过CCreateContext实现第二视图和文档的关联
CCreateContext context; context.m_pCurrentDoc = pDoc;//把视图放在当前文档
UINT m_ID = AFX_IDW_PANE_FIRST + 1;//设置标识作为CMainFrame的子窗口
CRect rect; //为了演示第一种多视图是实现方法,把Vew的实例创建放在了这里
m_pOtherView->Create(NULL, NULL, WS_CHILD, rect, m_pMainWnd, m_ID, &context);}
//切换时,设置活动视图,另外就是重新计算,这里要具体看RecalcLayout
……//里面会交换View窗口ID,是因为 CFrameWnd::RecalcLayout will allocate
// this "first pane" to that portion of the frame window's client area
//not allocated to control bars.
m_pOtherView->ShowWindow(SW_HIDE);
m_pFirstView->ShowWindow(SW_SHOW);
m_pMainWnd->SetActiveView(m_pFirstView);
m_pMainWnd->RecalcLayout();
m_pFirstView->Invalidate();
三、CMainFrame中添加不同的CChildFrame【3、4】
1、这个子窗口,只是创建了一个视图,没有指定context.m_pCurrentDoc,在CView::OnCreate()里面会报错。
2、加入文档后
四、总结
CMainFrame建立了MDIClient之后,会new CDocument,然后pFrame
对于文档管理,三、2中,可将模板放在保存一个位置,或者直接获取pDocTemplate,然后将pDoc加入到文档模板当中。
参考:1、MFC SDI单文档多视图的实现及自由切换(2种实现方式简析)
2、为啥交换窗口ID标识
3、MFC文档视图深入详解
4、深入分析MFC文档视图结构(项目实践)
对于多文档App而言,首先是创建CMainFrame窗口和它的子窗口MDIClient。当新建一个文档,则会new CDocument,顺便创建CChildFrame和它的子窗口CView,再次新建时,会建立另一个文档,创建另外一个CChildFrame和它的子窗口CView。对于不同视图,CView的ID标识是AFX_IDW_PANE_FIRST。在本次CChildFrame新建另外的CView时,ID标识要改变,以免重复。
向MDIClient发送WM_MDICREATE创建CChildFrame时,内部会分配子窗口的ID值,另外MDIClient在CManiFrame::OnCreate中调用到CMDIFrameWnd中的一个函数,里面创建时,Menu ID标识也是AFX_IDW_PANE_FIRST,但是MDIClient的创建 CLIENTCREATESTRUCT ccs的里面,可以指定子窗口id标识ccs.id,即子窗口CChildFrame的id标识从这个数字开始编号AFX_IDM_FIRST_MDICHILD。
若要获取激活窗口,则向MDIClient发送WM_GETACTIVATE消息,每个激活的CChildFrame父类CFrameWnd保存一个 CView* m_pViewActive,也就是CChildFrame会有一个主视图。
二、SDI单文档多视图的实现及自由切换【1、2】
主要是获取当前活动文档ActiveDocument,放到context.m_pCurrentDoc,然后再创建的时候,传上下文context信息。
classCMultiViewApp : publicCWinApp{
public:
CView* m_pFirstView;
CView* m_pOtherView;
int m_currentView;
CView* m_pView2;
CView* m_pView1;
}
CMultiViewApp::InitInstance()
{
CDocument* pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
//通过CCreateContext实现第二视图和文档的关联
CCreateContext context; context.m_pCurrentDoc = pDoc;//把视图放在当前文档
UINT m_ID = AFX_IDW_PANE_FIRST + 1;//设置标识作为CMainFrame的子窗口
CRect rect; //为了演示第一种多视图是实现方法,把Vew的实例创建放在了这里
m_pOtherView->Create(NULL, NULL, WS_CHILD, rect, m_pMainWnd, m_ID, &context);}
//切换时,设置活动视图,另外就是重新计算,这里要具体看RecalcLayout
……//里面会交换View窗口ID,是因为 CFrameWnd::RecalcLayout will allocate
// this "first pane" to that portion of the frame window's client area
//not allocated to control bars.
m_pOtherView->ShowWindow(SW_HIDE);
m_pFirstView->ShowWindow(SW_SHOW);
m_pMainWnd->SetActiveView(m_pFirstView);
m_pMainWnd->RecalcLayout();
m_pFirstView->Invalidate();
三、CMainFrame中添加不同的CChildFrame【3、4】
1、这个子窗口,只是创建了一个视图,没有指定context.m_pCurrentDoc,在CView::OnCreate()里面会报错。
CMainFrame::OnFuncTwo() { //仿照上面的思想,new Frame,点击一个菜单时,切换到这个CChildFrame m_pFuncOneFrame = new CDemoFrame(); CCreateContext context; context.m_pNewViewClass = RUNTIME_CLASS(CFuncOneView); //关联的视图类,又它新建一个视图对象 m_pFuncOneFrame->LoadFrame(IDR_MAINFRAME, WS_MAXIMIZEWS_OVERLAPPEDWINDOW, this, &context); m_pFuncOneFrame->SetWindowText(" 业务逻辑一 "); m_pFuncOneFrame->ShowWindow(SW_SHOWMAXIMIZED); m_pFuncOneFrame->InitialUpdateFrame(NULL,true); }
2、加入文档后
void CMainFrame::OnFuncOne() { // TODO: Add your command handler code here if (m_pFuncOneFrame != NULL) //已创建,则激活它 { m_pFuncOneFrame->MDIActivate(); return ; } m_pFuncOneFrame = new CDemoFrame(); CDemoDoc* m_pDoc = new CDemoDoc(); //new了一个文档 CCreateContext context; context.m_pNewViewClass = RUNTIME_CLASS(CFuncOneView); //传CView class context.m_pCurrentDoc = m_pDoc; m_pFuncOneFrame->LoadFrame(IDR_MAINFRAME, WS_MAXIMIZEWS_OVERLAPPEDWINDOW, this, &context); m_pFuncOneFrame->SetWindowText(" 业务逻辑一 "); m_pFuncOneFrame->ShowWindow(SW_SHOWMAXIMIZED); m_pFuncOneFrame->InitialUpdateFrame(NULL,true); }
四、总结
CMainFrame建立了MDIClient之后,会new CDocument,然后pFrame
CCreateContext context; context.m_pCurrentFrame = pOther;//NULL, context.m_pCurrentDoc = pDoc;//当前文档 context.m_pNewViewClass = m_pViewClass;//CDocTemplate中已经保存有它 context.m_pNewDocTemplate = this; pFrame->LoadFrame(m_nIDResource, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,NULL, &context)) //pParenWnd会在后面设置为MDIClient //其函数原型 virtual BOOL LoadFrame(UINT nIDResource,DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd* pParentWnd = NULL,CCreateContext* pContext = NULL);
对于文档管理,三、2中,可将模板放在保存一个位置,或者直接获取pDocTemplate,然后将pDoc加入到文档模板当中。
参考:1、MFC SDI单文档多视图的实现及自由切换(2种实现方式简析)
2、为啥交换窗口ID标识
3、MFC文档视图深入详解
4、深入分析MFC文档视图结构(项目实践)
相关文章推荐
- 【交互】MFC架构分析之多文档多视图1
- C++--深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(转载)
- C++--深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- C++--深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- C++--深入分析MFC文档视图结构(项…
- 深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- 深入浅出MFC文档/视图架构之实例剖析
- 转载:深入分析MFC文档视图
- C++--深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图结构(项目实践)
- 深入分析MFC 文档视图结构一
- 深入分析MFC文档视图结构(项目实践)
- 深入分析MFC文档视图