对象 | 可以访问的对象 |
---|---|
文档 | 调用 GetFirstViewPosition() 函数和 GetNextView() 函数可以访问文档的视图列表;调用 GetDocTemplate() 函数可以获取文档模板。 |
视图 | 调用 GetDocument() 函数可以获得与其相关的文档;调用 GetParentFrame() 函数可以获得框架对话框。 |
文档框架对话框 | 调用 GetActiveView() 函数可以获得当前视图;调用 GetActiveDocument() 函数可以获得与当前视图相连的文档。 |
MDI 框架对话框 | 调用 MDIGetActive() 函数可以获得当前激活的 CMDIChildWnd 对象。 |
MFC 提供了下面几个用于访问 CWinAPP 对象和其他全局信息的全局函数
函数名 | 功能 |
---|---|
AfxGetApp() | 获取 CWinAPP 对象指针 |
AfxGetInstanceHandle() | 获取当前应用程序的实例句柄 |
AfxGetResourceHandle() | 获取应用程序的资源句柄 |
AfxGetAppName() | 获取应用程序名称,等同于 CWinAPP 对象的 m_psExeName 成员变量。 |
BOOL CMFCApplication1App::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance();
// 初始化 OLE 库
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
EnableTaskbarInteraction();
// 使用 RichEdit 控件需要 AfxInitRichEdit2()
// AfxInitRichEdit2();
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
//设置注册表键
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU),即加载标准配置设置
// 注册应用程序的文档模板。 文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate; //定义多文档变量
pDocTemplate = new CMultiDocTemplate(IDR_MFCApplication1TYPE,
RUNTIME_CLASS(CMFCApplication1Doc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CMFCApplication1View));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); //增加到文档模板集合
// 创建主 MDI 框架窗口
CMainFrame* pMainFrame = new CMainFrame; //定义 CMainFrame 类
//装载框架
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
delete pMainFrame;
return FALSE;
}
m_pMainWnd = pMainFrame; //为主窗口类赋值
// 分析标准 shell 命令、DDE、打开文件操作的命令行
CCommandLineInfo cmdInfo; //定义命令行信息变量
ParseCommandLine(cmdInfo); //解析命令行
// 调度在命令行中指定的命令。 如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// 主窗口已初始化,因此显示它并对其进行更新
pMainFrame->ShowWindow(m_nCmdShow); //显示主窗口
pMainFrame->UpdateWindow(); //刷新主窗口
return TRUE;
}
MFC 中,在主框架下可以通过文档类和视图类进行数据管理。
CDocument 类提供文档类的基本功能。在文档/视图结构中,当文档数据被修改时,其对应的每个视图都必须反映这些修改,CDocument 类提供 UpdateAllView() 成员函数通知视图文档有变化,因此视图可以根据数据重绘界面。
CDocument 类核心函数
函数 | 功能 |
---|---|
AddView() | 附加视图到文档中 |
GetDocTemplate() | 返回描述文档类型的文档模板指针 |
GetFirstViewPosition() | 返回与文档相关的第一个视图,可用于枚举 |
GetNextView() | 枚举与文档相关的视图列表 |
GetTitle() | 返回与文档相关的数据文件的路径 |
IsModified() | 返回文档的标题 |
RemoveView() | 返回表示自从上次保存后,文档是否被修改过 |
SetModifiedFlag() | 从文档中卸载一个视图 |
SetPathName() | 设置标记,表示自从上次保存后,文档修改过 |
SetTitle() | 设置文档使用的数据文件的路径 |
UpdateAllViews() | 设置文档标题 |
CanCloseFrame() | 通知与文档相关的所有视图,文档数据发生了变化 |
DeleteContents() | 当清除文档时调用此函数 |
OnChangeViewList() | 向文档中添加视图或移除视图时调用此函数 |
OnCloseDocument() | 当关闭文档时调用此函数 |
OnNewDocument() | 当创建新文档时调用此函数 |
OnOpenDocument() | 当打开已存在的文档时调用此函数 |
OnSaveDocument() | 当保存文档到磁盘时调用此函数 |
ReportSaveLoadException() | 当打开或保存文档发生异常时调用此函数 |
GetFile() | 返回 CFile 对象的指针 |
ReleaseFile() | 释放文件,可以被其他程序调用 |
SaveModified() | 重载函数,询问用户是否可以保存文档 |
PreCloseFrame() | 框架对话框关闭前调用的函数 |
OnFileSendMail() | 通过邮件消息发送文档 |
OnUpdateFileSendMail() | 如果支持邮件功能,则打开发送邮件命令 |
从 CView 派生而来的视图类
派生的视图类 | 功能 |
---|---|
CView | 所有视图的基类 |
CCtrlView | CTreeView、CListView、CEditView和CRichEditView类的基类,这些类允许文档/视图结构使用 Windows 标准控件初始化 |
CEditView | 基于 Windows 编辑控件的简单视图;允许用户输入和编辑文本,用于创建简单的文本编辑程序 |
CRichEditView | 包含 CRichEditCtrl 对象的视图;与 CEditView 类似,主要区别在于此类处理格式化文本 |
CListView | 包含 CListCtrl 对象的视图 |
CTreeView | 包含 CTreeCtrl 对象的视图 |
CScrollView | CFormView、CRecordView 和 CDaoRecordView 的基类,实现滚动视图内容的功能 |
CFormView | 包含控件的对话框视图,基于对话框的应用程序提供一个或多个这样的窗体接口。 |
CHtmlView | Web 浏览器视图,允许用户浏览 WWW 站点、本地文件系统和网络中的文件夹,也可用于作为活动文档容器 |
CRecordView | 在控件中显示 ODBC 数据记录的窗体视图,与 CRowset 相连 |
CDaoRecordView | 在控件中显示 DAO 数据记录的窗体视图,与 CDaoRecordset 相连 |
COleDBRecordView | 在控件中显示 OLE DB 数据记录的窗体视图,与 CRowset 相连 |
上述类中,除了 CCtrlView 和 CDaoRecordView 外,其余都可以在 MFC 的应用向导中使用。
CView 类核心函数
函数 | 功能 |
---|---|
DoPreparePrinting() | 显示打印对话框并创建打印机设备上下文,当重载 OnPreparePrinting() 成员函数时,会调用此函数 |
GetDocument() | 返回与视图相关的文档 |
OnInitialUpdate() | 当第一次视图附加到文档上时,调用此函数 |
IsSelected() | 检测文档项是否被选择 |
OnActivateView() | 当激活视图时,调用此函数 |
OnActivateFrame() | 当激活包含视图的框架时,调用此函数 |
OnBeginPrinting() | 当开始打印任务时,调用此函数 |
OnDraw() | 在显示屏、打印或打印预览中渲染文档图像 |
OnEndPrinting() | 当结束打印任务时,调用此函数 |
OnEndPrintPreview() | 当退出打印预览时,调用此函数 |
OnPrePareDC() | 当显示屏调用 OnDraw() 成员函数前,以及为打印或打印预览调用 OnPrint() 成员函数前调用此函数 |
OnPreparePrinting() | 在打印或打印预览文当前,调用此函数 |
OnPrint() | 打印或打印预览一页文档 |
OnUpdate() | 通知视图文档内容已经修改 |
文档/视图结构应用程序最要的是创建和管理文档;创建文档的方式有两种:
1)使用 File|New命令创建新文档,由 CDocument类的 NoNewDocument 重载函数完成文档初始化。
2)使用 File|Open 命令打开文档并从中读取内容,由 CDocument 类的 OnOpenDocument 重载函数完成文档初始化。
创建文档后,需要创建视图并完成试图初始化,可以通过重写 CView 类的 OnInitialUpdate 成员函数完成初始化;如果要使文档内容每次发生改变时,都能重新初始化或调整视图显示则需要重载视图类的 OnUpdate 成员函数。
文档的生命周期如下:
1)调用文档的构造函数,动态创建文档对象;
2)每个新文档都会调用 CDocument 类的 OnNewDocument 或 OnOpenDocument,在这两个函数里初始化自定义数据;
3)在文档生命周期内,用户可以进行交互;如通过视图选择或修改文档数据,视图将这些修改传递给文档,文档保存修改并更新对应的视图显示;
4)当文档关闭时,框架调用 DeleteContents 函数进行内存释放;
5)调用文档类的析构函数。
要实现多视图,文档对象要保存一个视图列表,提供增加视图或移除视图的成员函数,并提供 UpDateAllView 函数,允许当文档数据改变时,通知多个视图。MFC 中存在以下3种类型的多视图结构:
1)在多文档框架中,支持多个同类型的视图对象。此种结构下,用户选择 New|Windows 命令打开相同文档的新视图框架,然后可以通过多个视图框架查看同一文档内容。
2)在单文档框架中,支持多个同类型视图对象,即分割对话框——将单文档的视图空间分为多个视图。此种方式下,框架会从同一个视图类中创建多个视图对象。
3)在单文档框架中,支持多个不同类型的视图对象。此方式下,多个视图共享单个框架对话框;视图从不同类中构造,每个视图提供对相同文档的不同方式的视图。如一个视图在普通模式下显示字处理文档,而另一个视图可以在全屏模式下显示。
视图的功能是图形化显示文档数据,并接收用户的输入,对视图的操作有以下几种:
1)重写 OninitialUpdate() 函数完成视图类的特殊初始化。
2)在视图类的 OnDraw() 成员函数中,编写显示文档数据的代码。
3)重写 OnUpdate() 函数完成当视图需要重绘时的指定操作。
4)连接适当的 Windows 消息和用户接口对象(如菜单项)到视图类的消息处理函数中。
5)完成用户输入的处理。
6)对于多页文档,必须重载 OnPreparePrint() 初始化打印对话框,传入打印页码和其他信息。
在文档/视图结构的应用程序中,几乎所有的绘制工作都在视图的 OnDraw 成员函数中实现,重写视图类的步骤:
1)通过调用文档类中的获取文档数据的成员函数获取数据;
2)通过调用框架传给 OnDraw 函数的设备上下文对象的成员函数显示数据。
当文档数据发生变化时,视图必须重绘反映变化——通过调用 UpDataAllView 函数,而UpDateAllView 函数调用每个视图的 OnUpDate 函数。
MFC 为了提高重绘速度,在CDocument 类的 UpDateAllView 函数和 CView 的OnUpdate函数传入文档修改部分的信息,这样程序可以只定位到需要重绘的区域,OnUpDate 的函数原型:
void MFCSampleView::OnUpdate(
CView* pSender, //事件发生对象
LPARAM LHint, //通过此参数可以传入需要的数据
CObject* pHint //通过此参数可以传入继承自CObject类的派生类对象
)
当视图需要重绘,操作系统会给视图发送 WM_PAINT 消息,而视图的 OnPaint() 处理函数会响应此消息,通过创建 CPainDC 类的设备上下文对象,并调用 OnDraw 函数;一般 OnPain 不需要重写。
设备上下文DC包含设备绘制属性,如显示器或打印机信息;要在屏幕上绘制,通过OnDraw传入的CPainDC对象,要在打印机上绘制,通过OnDraw传入的CDC对象建立当前打印机的链接。
在视图绘制时,首先要获取文档指针,然后通过设备上下文绘制,下面显示了OnDraw函数的处理过程
void C文档视图应用程序View::OnDraw(CDC* pDC)
{
C文档视图应用程序Doc* pDoc = GetDocument(); //获取与视图相关的文档
ASSERT_VALID(pDoc); //验证文档对象的有效性
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CString data = pDoc->GetData(); //获取文档数据
CRect rect;
GetClientRect(&rect); //获取客户区域
//设置文本对齐方式为居中
pDC->SetTextAlign(TA_BASELINE | TA_CENTER);
//在客户区中间绘制
pDC->TextOut(rect.right / 2, rect.bottom / 2, data, data.GetLength());
}
[外链图片转存失败(img-zLf9awNV-1564448097906)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1557745348295.png)]
序列化就是从持久存储媒体(如磁盘)中读数据或向其中写数据的过程。
基本思想就是对象可以记录当前状态,由成员变量标识序列化存储;之后,对象可以通过序列化存储中读取或反序列化对象状态重新创建对象。
关键点就是对象本身负责读取和记录自身状态。
MFC 中,通过 CArchive 归档对象实现序列化,可以满足很多应用程序的需求,如读取整个文件到内存的应用程序;但是有时候使用归档对象是不能满足需要的,如数据库程序,只编辑大文件的一部分,程序只能写入文本文件,并且多个程序共享数据会发生访问冲突,此时可以使用 CFile 对象实现序列化。
使用 CFile 类的 Open()、Read()、Write()、Close()和Seek() 成员函数打开文件、移动文件中指定的文件指针、在指定点读取记录。
可以使用 CArchive 类的 GetFile 成员函数获取 CFile 对象的指针。
默认情况下,CDocument 类使用序列化处理 File 菜单的 Save 和 Save As 命令;MFC 框架在 CDocument 类生成了 Serialize() 成员函数提供对序列化的默认实现,只需写入相应的处理代码。
MFC 中,在要序列化的对象和存储媒体之间,使用 CArchive 类对象作为中间对象并总是与 CFile 对象相连,包含序列化必须的信息——文件名以及请求操作类型(读操作、写操作)。
案例:
void C文档视图应用程序Doc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: 在此添加存储代码
ar << m_data;
}
else
{
// TODO: 在此添加加载代码
ar >> m_data;
}
}
[外链图片转存失败(img-3ClofU60-1564448097907)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1557824461394.png)]
MFC 支持在视图中使用滚动条和自动计算显示的框架对话框的大小。
任何视图都可以在 OnHScroll() 和 OnVScroll() 成员函数中处理滚动条消息。
在 MFC 中实现支持滚动条的视图,按以下步骤操作即可:
1)将需要支持滚动条的视图类的基类修改为 CScrollView,可以通过替换 CView 基类实现。
2)在视图类增加存储区的 CRect 成员变量,用于记录视图显示区域。
3)修改视图类的构造函数和 OnInitialUpDate() 函数,在其中设置滚动条参数。
C文档视图应用程序View::C文档视图应用程序View() noexcept
{
// TODO: 在此处添加构造代码
m_rect = CRect(0, 0, 1024 * 3, -1024 * 3); //初始化视图区域
}
void C文档视图应用程序View::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
//定义逻辑窗口大小为 40cm X 30cm
CSize sizeTotal(40000, 30000);
//定义每页大小为10cm X 10cm
CSize sizePage(sizeTotal.cx / 4, sizeTotal.cy / 4);
//定义每行大小为0.4cm X 0.3cm
CSize sizeLine(sizeTotal.cx / 100, sizeTotal.cy / 100);
//设置滚动参数
SetScrollSizes(MM_HIMETRIC, sizeTotal, sizePage, sizeLine);
}
4)在 OnKeyDown() 按键处理函数中处理滚动按键的单击事件。
void C文档视图应用程序View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar)
{
case VK_UP: //按向上按键
OnVScroll(SB_LINEUP, 0, NULL);
break;
case VK_DOWN: //按向下按键
OnScroll(SB_LINEDOWN, 0, NULL);
break;
case VK_LEFT: //按向左按键
OnHScroll(SB_LINELEFT, 0, NULL);
break;
case VK_RIGHT: //按向右按键
OnHScroll(SB_LINERIGHT, 0, NULL);
break;
case VK_PRIOR: //上页按键
OnVScroll(SB_PAGEUP, 0, NULL);
break;
case VK_NEXT: //下页按键
OnVScroll(SB_PAGEDOWN, 0, NULL);
break;
case VK_HOME: //开始按键
OnVScroll(SB_TOP, 0, NULL);
OnHScroll(SB_LEFT, 0, NULL);
break;
case VK_END: //结束按键
OnVScroll(SB_BOTTOM, 0, NULL);
OnHScroll(SB_RIGHT, 0, NULL);
break;
default:
break;
}
CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}
5)在视图类的 OnDraw() 函数中绘制数据内容。
pDC->Ellipse(m_rect); //在文本中绘制圆形
6)在 OnLButtonDown() 函数中处理 WM_LBUTTONDOWN 消息
void C文档视图应用程序View::OnLButtonDown(UINT nFlags, CPoint point)
{
CClientDC dc(this); //获取客户区上下文
OnPrepareDC(&dc); //转换上下文坐标
CRect rectDevice = m_rect;
//将设备区域从逻辑坐标转换为设备坐标
dc.LPtoDP(rectDevice);
InvalidateRect(rectDevice); //重绘设备区域
CScrollView::OnLButtonDown(nFlags, point);
}
MFC 提供 CSplitterWnd 类支持对框架窗口的分割,可以将框架窗口分割为两个或多个可滚动的面板。
对话框分割分为两种:
1)动态分割:允许用户将当前窗口分割为多个面板,通过滚动条查看文档的不同部分,同时允许用户动态删除分割窗口;但是动态分割后的各个窗口对应的视图类的类型必须是相同的,而且采用动态分割最多将视图分割为2*2子窗口。
2)静态分割:是指在程序启动时,就将窗口分割好了,每个分割后的窗口作用可以是不同的,因为静态分割允许每个面板对应的视图类型是不同的,支持将视图分割为 16*16 个子窗口。
首先在 MFC 应用程序向导中,单击“用户界面功能”按钮,选择“拆分窗口”复选框。
在经过上面步骤后,程序会自动添加对分割条的支持,会在框架类中定义 CSplitterWnd 类对象 m_wndSplitter,并在框架类的 OnCreateClent() 函数中调用 Create() 函数来动态分割对话框;在 Create 函数中需要指定当面板太小不能显示全部内容时的最小行高和列宽。
调用 Create 函数后,还可以通过调用 SetColumnInfo 函数和 SetRowInfo 函数调整最小值。
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
return m_wndSplitter.Create(this,
2, 2, // TODO: 调整行数和列数
CSize(100, 100), // TODO: 调整最小窗格大小
pContext);
}
[外链图片转存失败(img-75g2q81P-1564448097908)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1557836617094.png)]
创建静态分割对话框步骤:
1)同动态分割对话框一样
2)根据需要添加 CSplitterWnd 成员变量,例如三行三列的对话框分割,则需要定义两个 CSplitterWnd 成员变量—— m_wndSplitter1 和 m_wndSplitter2
3)重载父框架类的 CFrameWnd::OnCreateClient() 成员函数,在其中调用 CSplitterWnd 类的 CreateStatic() 成员函数。
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
//创建一个静态分栏窗口,分为三行一列
if (m_wndSplitter1.CreateStatic(this, 3, 1) == NULL)
return FALSE;
// 将CView1连接到0行0列窗格上
m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(View1), CSize(10, 10), pContext);
// 将CView2连接到1行0列窗格上
m_wndSplitter1.CreateView(1, 0, RUNTIME_CLASS(CView2), CSize(10, 10), pContext);
// 将第2行再分开1行3列
if (m_wndSplitter2.CreateStatic(&m_wndSplitter1, 1, 3, WS_CHILD | WS_VISIBLE,
m_wndSplitter1.IdFromRowCol(2, 0)) == NULL)
return FALSE;
//将CView3类连接到第3行的第1列
m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CView3), CSize(300, 200), pContext);
//将CView4类连接到第3行的第2列
m_wndSplitter2.CreateView(0, 1, RUNTIME_CLASS(CView3), CSize(300, 200), pContext);
//将CView5类连接到第3行的第3列
m_wndSplitter2.CreateView(0, 2, RUNTIME_CLASS(CView5), CSize(300, 200), pContext);
return TRUE;
//return m_wndSplitter.Create(this,
// 2, 2, // TODO: 调整行数和列数
// CSize(10, 10), // TODO: 调整最小窗格大小
// pContext);
}
//MDISampleDoc.h
CString m_Data;
//MDISampleDoc.cpp
m_Data = "Hello MDI!";
//View1.h
#pragma once
#include
#include"MDISampleDoc.h"
class CView1 : public CEditView
{
protected:
CView1(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CView1)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CView1)
public:
virtual void OnInitialUpdate();
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CView1();
CMDISampleDoc* GetDocument(); // non-debug version is inline
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(CView1)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//View1.cpp
#include "stdafx.h"
#include "View1.h"
#include"MDISample.h"
#include"MDISampleDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CView1, CEditView)
CView1::CView1()
{
}
CView1::~CView1()
{
}
BEGIN_MESSAGE_MAP(CView1, CEditView)
//{{AFX_MSG_MAP(CView1)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CView1 drawing
void CView1::OnDraw(CDC* pDC)
{
}
/
// CView1 diagnostics
#ifdef _DEBUG
void CView1::AssertValid() const
{
CEditView::AssertValid();
}
void CView1::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
}
#endif //_DEBUG
/
// CView1 message handlers
CMDISampleDoc* CView1::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMDISampleDoc)));
return (CMDISampleDoc*)m_pDocument;
}
void CView1::OnInitialUpdate()
{
CEditView::OnInitialUpdate();
CMDISampleDoc* pDoc = GetDocument();
this->GetEditCtrl().SetWindowText(L"这里是编辑框视图CView1,文档内容=" + pDoc->m_Data);
}
//View2.h
#pragma once
#include
#include"MDISampleDoc.h"
#include"resource.h"
class CView2 : public CEditView
{
protected:
CView2(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CView2)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CView1)
public:
virtual void OnInitialUpdate();
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CView2();
CMDISampleDoc* GetDocument(); // non-debug version is inline
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(CView1)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//View2.cpp
#include "stdafx.h"
#include "View2.h"
#include"MDISample.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CView1
IMPLEMENT_DYNCREATE(CView2, CEditView)
CView2::CView2()
{
}
CView2::~CView2()
{
}
BEGIN_MESSAGE_MAP(CView2, CEditView)
//{{AFX_MSG_MAP(CView1)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CView1 drawing
void CView2::OnDraw(CDC* pDC)
{
}
/
// CView1 diagnostics
#ifdef _DEBUG
void CView2::AssertValid() const
{
CEditView::AssertValid();
}
void CView2::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
}
#endif //_DEBUG
/
// CView1 message handlers
CMDISampleDoc* CView2::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMDISampleDoc)));
return (CMDISampleDoc*)m_pDocument;
}
void CView2::OnInitialUpdate()
{
CEditView::OnInitialUpdate();
CMDISampleDoc* pDoc = GetDocument();
this->GetEditCtrl().SetWindowText(L"若道天涯无回路,漫漫黄沙掩枯骨!文档内容=" + pDoc->m_Data);
}
//MDISampleView.cpp
void CMDISampleView::OnDraw(CDC* pDC)
{
CMDISampleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
pDC->TextOutW(0, 0, L"高楼独上,望尽天涯路,欲寄彩笺兼尺素,山长水阔知何处。文档内容=" + pDoc->m_Data);
}
//MDISample.cpp
BOOL CMDISampleApp::InitInstance()
{
//....
// 注册应用程序的文档模板。 文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MDISampleTYPE,
RUNTIME_CLASS(CMDISampleDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CMDISampleView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
CMultiDocTemplate* pDocTemplate1;
pDocTemplate1 = new CMultiDocTemplate(IDR_MENU1,
RUNTIME_CLASS(CMDISampleDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CView1));
if (!pDocTemplate1)
return FALSE;
AddDocTemplate(pDocTemplate1);
CMultiDocTemplate* pDocTemplate2;
pDocTemplate2 = new CMultiDocTemplate(IDR_MENU2,
RUNTIME_CLASS(CMDISampleDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CView2));
AddDocTemplate(pDocTemplate2);
//...
}