我们都知道MFC里的SDI程序实现了Frame-Doc-View结构,在这种模型中,实现了一个文档对应一个VIEW,而MDI则实现了多文档多视图模型。
但很多时候我们的程序不需要多文档,但希望能处理多个VIEW,这时候可能会有人想到拆分窗口SplitterWnd,拆分窗口能在同一个框架里同时显示
多个视图(VIEW)。不过可能有人喜欢虽然存在多个视图,但同一时间只想显示一个视图。例如某些软件有几个功能块,如学生管理的学员管理、课程管理、生活管理等模块。
那么能否在SDI程序中实现这样的多视图支持呢?答案是肯定的。我们只需要改造CFrameWnd,让它实现多视图即可。
首先我们继承CFrameWnd,实现一个派生类CMutiViewFrame
并重写其中几个虚函数,并添加加入视图和选择视图的接口。如下所示:
AddView是添加视图
参数pViewCreater为动态创建VIEW的CRuntimeClass,pContext为MFC的创建索引参数。具体用法在后面说明
CMutiViewFrame的实现可参考附件(http://download.youkuaiyun.com/source/1460151)。此处就不列出了。为了方便使用vector保存视图指针。你可以使用其它的数据结构。
需要使用多视图类,大家先用向导生成一个SDI的程序。
然后修改MainFrm.h和MainFrm.cpp使其继承自CMutiViewFrame。如下:
#include "MutiViewFrame.h"
class CMainFrame : public CMutiViewFrame
{
protected: // 仅从序列化创建
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// 属性
public:
// 操作
public:
// 重写
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// 实现
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // 控件条嵌入成员
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
protected:
CFormFriendLink *m_pFriendView;
// 生成的消息映射函数
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
并把MainFrm.cpp中的所有CFrameWnd替换为CMutiViewFrame
如何添加视图?
首先点菜单的项目,然后添加类,选择添加MFC类。添加一个自定义的View类,可以是(CView或CFormView等)
假设添加了一个CMyFormView
然后在
CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数最后,return 0 前面添加如下代码
CCreateContext* pContext = (CCreateContext*)lpCreateStruct->lpCreateParams;
AddView( RUNTIME_CLASS(CMyFormView), pContext );
即添加了另一个视图
然后剩下的就是视图切换了,只要在需要切换的地方,如工具栏按钮的响应函数里,添加
CMutiViewFrame *pMainFrame = reinterpret_cast<CMutiViewFrame*>( theApp.GetMainWnd() );
if( NULL != pMainFrame )
{
pMainFrame->SetCurrentView( 0 );
}
其中pMainFrame->SetCurrentView( 0 );设置第一个视图。
pMainFrame->SetCurrentView( 0 );// 第一个视图,即默认的视图
pMainFrame->SetCurrentView( 1 );// 第二个视图,即CMyFormView
SDI支持多视图类实现参考附件:
http://download.youkuaiyun.com/source/1460151