《深入浅出MFC》花了很大的笔墨讲Documnet/View,并指出MFC之所以为Application Framework在于Document/View。
Document/View使得MFC成为一个完整的程序模型,具备标准Windows应用软件所需的一切基本功能,像是文件存取、打印预览、数据交换...,以及这些功能的使用接口(工具栏、状态栏、菜单、对话框)。静态情况下,MFC是一组类库,但在程序运行时它就生出了一群有活力的对象组。最重要的是,这些对象之间的关系早已建立好,不必程序员操心。然而,在“真正的事情”上,比如数据的处理、数据的显示,MFC所能提供的,无一不是单单一个空壳而已。MFC只是帮我们把浩瀚的API们,利用面向对象的原理、逻辑地组织起来,使它们具备抽象化、封装化、继承性、多态性、模块化的性质。MFC使得“整个程序会自动运行良好”,比如这些都是例子:
1.按下【File/Open】,MFC会激活对话框,让你指定文件名,然后再自动调用::Serialize读文件。MFC还会调用::OnDraw,把数据显示出来。
2.屏幕状态改变时,产生了WM_PAINT,MFC会自动调用你的::OnDraw,传一个Display DC,让你重新绘制窗口内容。
3.按下【File/Print...】,MFC会自动调用你的::OnDraw,这次传进去的是个Printer DC,因此绘图操作的输出对象就成了打印机。
所以,MFC把模块与模块之间的消息传递路径以及各函数的功能职责都已确定好。即使用者接口已经标准化,程序模块之间的沟通或消息的流动也已确定好了。
MFC希望程序员把精力花在数据结构的设计以及真正的数据显示上。我们一般也是这么做得,比如我现在的项目,但vs向导帮我建立的标准控件及功能,对我来说都是多余的,首先我需要把菜单、工具、属性等都删除,再在这个框架下添加我需要的功能,因此我怀疑我是否使用了Document/View?书中以“新建文件”为例子来说明Documnet/View的Document Template是如何管理CDocument/CView/CFrameWnd的。
Document Template通过下面的代码:
BOOL CScribbleApp::InitInstance()
{
...
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_SCRIBTYPE,
RUNTIME_CLASS(CSribbleDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CScribbleView));
AddDocTemplate(pDocTemplate);
...
}
持有了Document、View、Frame的CRuntimeClass指针,Document Template可借由Document、View、Frame之CRuntimeClass指针来动态创建。
而我正是从修改InitInstance开始我的程序的,将CScribbleView替换为我的View。在pDocTemplate调用OpenDocumentFile时创建我的应用程序界面。