单文档多视图
本节演示了如何在一个框架中显示两个视图。
1.实例说明
在MFC中,视图必须存在于框架之中,而单文档只有一个框架,所以一次只能显示一个视图,如果想显示新视图必须关闭当前视图。如果想同时显示两个视图可以用分割窗口。
本示例用于查询学生信息,数据存在文档类中,用户可以在第一个视图中输入学号,单击“查找”按钮查找学生消息,结果会显示在第二个视图中,效果如图1-53所示。

图1-53 Ex010205.exe效果图
2.实现
具体步骤如下:
(1)创建一个单文档的工程Ex010205,在应用程序向导的第6步中将视图类的基类改成CFormView,其他使用默认。
(2)增加一个新类COutPutView派生于CScrollView。
(3)在CMainFrame中增加一个保护级的成员变量CSplitterWnd m_wndSplitter 。
(4)利用类向导重载CMainFrame类的虚函数OnCreateClient。
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// 创建拆分器窗口
if (!m_wndSplitter.CreateStatic(this, 1, 2))
return FALSE;
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CEx010205View), CSize(500, 100), pContext) ||
!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(COutPutView), CSize(100, 100), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
return TRUE;
}
在MainFrm.cpp包含2个文件,加上后就包含了5个文件。
#include "stdafx.h"
#include "Ex010205.h"
#include "MainFrm.h"
#include "OutPutView.h"
#include "Ex010205View.h"
在Ex010205View.h中包含Ex010205Doc.h。
(5)在Ex010205Doc.h中增加新类:
class CStudent
{
public :
int m_iStuNo ;//学号;
int m_iScore ;//分数;
};
在Ex010205Doc.h中包含Afxtempl.h,为CEx010205Doc增加两个成员。
protected:
CArray<CStudent,CStudent&> m_arStus ;//记录所有的学生信息
public:
CStudent i_CurStu ;//记录当前信息
在文档类的构造函数中,对这些变量进行初始化。
CEx010205Doc::CEx010205Doc()
{
CStudent stu ;
stu.m_iStuNo = 1000 ;
stu.m_iScore = 99 ;
m_arStus.Add(stu);
stu.m_iStuNo = 1001 ;
stu.m_iScore = 59 ;
m_arStus.Add(stu);
stu.m_iStuNo = 1002 ;
stu.m_iScore = 79 ;
m_arStus.Add(stu);
i_CurStu = m_arStus[0] ;
}
(6)在OutPutView。h中包含Ex010205Doc.h,修改COutPutView::OnDraw函数。
void COutPutView::OnDraw(CDC* pDC)
{
CEx010205Doc* pDoc = (CEx010205Doc*) GetDocument();
CString str ;
str.Format("学号 = %d 成绩 = %d ",pDoc->i_CurStu.m_iStuNo,pDoc->i_CurStu.m_iScore);
pDC->TextOut(0,100,str);
}
(7)为CEx010205Doc增加一个公有成员函数SetCurStu(int iStuNo)。
bool CEx010205Doc::SetCurStu(int iStuNo)
{
for(int i = m_arStus.GetSize() - 1 ; i >= 0 ; i-- )
if( iStuNo == m_arStus[i].m_iStuNo )
{
i_CurStu = m_arStus[i] ;
break ;
}
return (i >= 0 ) ;//i >=0 表示已经找到,否则表示没有找到
}
(8)在对话框IDD_EX010205_FORM上加1个编辑控件和1个按钮。编辑控件的ID为IDC_STUNO,按钮的控件的ID为ID_FIND,标题为“查找”。为编辑控件关联一个int型的变量m_iStuNo,为按钮增加响应函数,具体代码如下:
void CEx010205View::OnFind()
{
CEx010205Doc* pDoc = GetDocument();
if(NULL == pDoc )
{
ASSERT(false);
return ;
}
UpdateData();
if(!pDoc->SetCurStu(m_iStuNo))
{
AfxMessageBox("没有找到此学生");
return ;
}
pDoc->UpdateAllViews(NULL);
}
(9)按Ctrl+F5键创建并运行Ex010205.exe,在编辑框中输入一个数(合法数据是1000~1002),单击“查找”按钮,右边的视图会显示此学生的信息。
(10)为了便于用户查看不及格的学生,红色显示不及格的学生。修改后的代码如下。
void COutPutView::OnDraw(CDC* pDC)
{
CEx010205Doc* pDoc = (CEx010205Doc*) GetDocument();
if(pDoc->i_CurStu.m_iScore < 60 )
pDC->SetTextColor(RGB(255,0,0));
CString str ;
str.Format("学号 = %d 成绩 = %d ",pDoc->i_CurStu.m_iStuNo,pDoc->i_CurStu.m_iScore);
pDC->TextOut(0,100,str);
}