MFC中单文档程序框架

新建一个Example单文档工程,应用向导可以自动地生成MFC应用的各个C++类。
MFC中单文档程序框架

1. 应用类及全局对象(CExampleApp
theApp 是唯一一个在程序形成的时候就存在的全局变量,CExampleApp类继承于CwinApp类,MSDN中CwinApp的继承关系如下
MFC中单文档程序框架
从继承关系当中,我们发现theApp是作为程序的实体而存在的,是单文档程序的核心。应用类封装了Windows应用的初始化,运行以及终止的全过程。对于每一个基于框架的应用,它必须有一个且只能有一个派生于CWinApp的类对象。这个对象是全局对象,因此它在创建任何窗口前首先被构造。类CWinApp提供了几个关键的可重载的虚成员函数,他们是InitInstanceRunExitInstance以及OnIdle等。而且,在程序中可以随时调用全局函数AfxGetApp,以便获得CWinApp类对象的指针。BOOL CExampleApp ::InitInstance()这个函数,包含了单文档程序中重要的信息,特别要提到的是一下的一段代码:

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CExampleDoc),
RUNTIME_CLASS(CMainFrame),       // main SDI frame window
RUNTIME_CLASS(CExampleView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
接下来对剩下的三个类对象做分析

2. CMainFrame

框架类表示应用程序的主框架窗口,其主要作用是响应标准的窗口消息,不过,它通常先将消息按照一定的次序传递给视图类以及文档类等其他命令处理类,另外,它还为视图类提供可视化的边框,同时也包括标题栏,一些标准的窗口组件等。 Cmianframe 的继承关系如下:
MFC中单文档程序框架

3.视图类(CExampleView
该类占有框架窗口的客户区,主要负责显示文档数据,也为文档对象和用户之间提供了用以交互的可视接口,另外,也完成了与文档打印相关的操作,通常,一般的绘制操作都是在该类中完成,因此有时也称视图类窗口为“绘制窗口”。
MFC中单文档程序框架
要注意的有几点,第一,因为mianfram是没有视图的,因此如果在mainframe相应Onpaint消息,自然是可以响应这个消息的,但是在绘制当中如何也不会出现预想的绘制内容,为什么呢? 嘿嘿,可以想象一下你在一个word程序里面,当你关闭了所有的白板(视图)的时候,你会发现你已经无法在编写文字,道理是一样的,在mainframe里面进行绘制,程序是没有问题,但是绘制的内容是在灰色上面,windows不予显示的。
第二点你可以发现在对菜单,和工具条的单击消息进行相应的时候你可以将消息响应函数添加到cmainframe也没有将消息响应函数调价到cview当中,但是你会惊奇的发现,两者只在一个地方相应的时候,消息响应函数没有问题都能正确的执行,但是如果同时对一个按钮或者菜单进行单击消息响应的时候,你会发现windows会执行的Cview里面的消息响应函数。具体消息路径会在下面叙述。

 

4.文档类(CExampleDoc
文档类实际上是一种数据结构,该类实现了对这种结构的封装以利于管理,通常,它不但包含应用中所需的数据,而且也包含了处理这些数据的方法,另外,文档类还可以为应用提供与其存储的数据相关的服务。
在CMianFrame中可以使用GetActiveDocument()
Cview类中可以使用:这里要注意一点,在Cview类中包含了一个Cdocument的对象m_pDocument这个对象即使指向Doc类的基类对象的,而要实现基类对象到现在doc类对象的转换只要添加如下函数即可
inline CStockAppDoc* CStockAppView::GetDocument()
return (CStockAppDoc*)m_pDocument; }
则可以实现。

 

5.“关于”对话框类(CAboutDlg
该类封装了用于显示软件版本,版权等相关信息的“关于”对话框,通常不需要对它进行任何的编程。而只需要使用对话框资源编辑器对对话框模板进行简单的编辑即可。

6. 其他说明:
1) 消息路径如下:
SDI(单文档)界面中,菜单响应遵循这样一个顺序:菜单消息先由CMainFrame类接收,CMainFrame并不直接在内部寻找对应的相应函数,而是到CView类寻找。如果CView类有该消息的响应函数,那么就直接调用CView类中的响应函数,否则,转到CDoc类寻找,如果CDoc类中存在该消息的响应函数,那么就直接调用CDoc类中的响应函数,否则,返回到CMainFrame类寻找。如果CMainFrame类中也没有,返回到CApp类中寻找。如果在CApp类中也没有找到,表示没有该菜单的响应函数。
2) 主框架(CFrameWnd)中访问视图(CView):
CView* GetActiveView() const;
通常定义的视图为CView的派生类,在调用自定义视图对象的方法时
应该这样写:((CMouseKeyView*)GetActiveView())->MyFunc();
3)主框架(CFrameWnd)中访问文档(CDocument):
       GetActiveDocument,返回CDocument对象;
4)在视图(CView)中访问文档(CDocument):
inline CMouseKeyDoc* CMouseKeyView::GetDocument() {return (CMouseKeyDoc*)m_pDocument;}
5)在视图(CView)中访问框架(CFrameWnd)
CFrameWnd* GetParentFrame() const;
6)在文档(CDocument)中访问框架(CFrameWnd)
CWnd* AfxGetMainWnd();
CWnd* AfxGetApp()->m_pMainWnd;
7)在文档(CDocument)中访问视图(CView)
UpdateAllViews
功能:通知所有的视图文档已被修改的信息
原型:
void UpdateAllViews(
CView* pSender, // 要更新的视图指针,如果希望更新所有视图,将此参数设为NULL
LPARAM lHint=0L, // 包含更改消息的通知
CObject* pHint=NULL // 保管更改消息的对象
     )
8)在其他类中访问文档类(CDocument)
CDocument* GetDocument()
{
CFrameWnd* frm=(CFrameWnd*)::AfxGetMainWnd();
ASSERT(frm);
CDocument* pDoc=frm->GetActiveDocument();
ASSERT(pDoc);
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CMouseKeyDoc)));
return (CMouseKeyDoc*)pDoc;
}
7.MFC程序流程小结
1)Windows将用户程序装入内存
2)构造全局对象theApp,在程序被装入时,所有全局对象都会立刻被创建。
3)Windows调用全局函数WinMain,它是类库的惟一实例
4)WinMain里面只调用函数AfxWinMain
5)AfxWinMain执行AfxWininit,调用AfxinitThred,接着
6)AfxWinMain执行InitApplication,然后执行InitinstanceInitinstanceCWinApp的虚函数,在此改写。
7)InitInstance函数里面启动文档的装入以及主要框架和视图显示处理过程。
8)在这里new 一个CMyFrameWnd CMyFrameWnd构造函数调用Create产生主窗口
9)InitInstance 执行ShowWindow,UpdateWindow,发出WM_PAINT
10)WinMain调用theAppRun函数,它启动窗口消息和命令消息的传递处理过程。
11)单击file/close,则发出WM_CLOSE
12)CMainFrame交默认处理
13)调用::DestroyWindow发出WM_DESTROY
14)默认处理调用::postQuitMessage 发出WM_QUIT
15)CWinapp::Run收到WM_QUIT结束内部循环,调用ExitInsance(CCExcmpleApp改写 Exitinstance,则调用CCExcmpleApp::ExitInstance;
16)ExitInstance函数负责完成应用程序结束之前的清除工作。
17)ExitInstance函数返回时,Run函数也返回了,MFC完成了一些清除工作,Windows终止应用程序
18)回到AfxWinMain,执行AfxWinTerm,程序结束!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值