MFC学习记录1

 

一、MFC六大关键技术

1、MFC初始化----寻找main函数

  C++规定,全局对象的构造将比main或WinMain函数更早。 

  首先是全局构造

    CObject构造函数 -> CCmdTarget -> CWinThread -> CWinApp -> theApp构造函数

  然后进入WinMain函数

    WinMain -> AfxWinMain -> AfxWinInit -> theApp.InitApplication -> theApp.InitInstance

  接着执行线程过程。

    theApp.Run()

  最后清理

    AfxWinTerm

 2、执行时类型识别(RTTI)-- -- 查询父子关系(true or false)

  CRuntimeClass的实现要通过几个复杂的宏DECLARE_DYNAMIX(Cxxx)和IMPLEMENT_DYNAMIC(Cxxx,Cxxxbase),在类内部声明这两个宏,就可以将该类加入到类型识别库。而CObject的函数IsKindOf()则可以指向任何派生至CObject的类,然后调用它就可以找到基类。

 3、动态生成(Dynamic Creation) -----  如何从文件中读取一个类并实现它

  动态生成也通过CRuntimeClass来实现,加入两个成员变量,并通过宏来实现。DECLARE_DYNCREATE 和IMPLEMENT_DYNCREATE 。

 4、永久保存(Persistence) -- -- 将对象写入到文件(Serialize)

  这需要用到宏DECLARE_SERIAL  / IMPLEMENT_SERIAL,以及CObject的虚函数 virtual void Serialize(CArchive& ar);

 5 、消息映射(Message Mapping)---- 消息如何获取

  宏DECLARE_MESSAGE_MAP / BEGIN_MESSAGE_MAP / END_MESSAGE_MAP

复制代码

 6、命令绕行(Command Routing)---- 消息流动方向

   一般Window消息(WM_xxx),一定是从子类流向父类,不可能旁流。

   命令消息WM_COMMAND 的消息流向比较另类,可以横向流动。

 

二、MFC生死因果

程序的诞生:

  Application object 产生,内存于是获得配置,初值亦设立了。

  Afx WinMain 执行AfxWinInit,后者又调用AfxInitThread,把消息队列尽量加大到96。

  Afx WinMain 执行InitApplication。这是CWinApp 的虚拟函数,但我们通常不改写它。

  AfxWinMain 执行InitInstance。这是CWinApp 的虚拟函数,我们必须改写它。

  CMyWinApp::InitInstance 'new' 了一个CMyFrameWnd 对象。

  CMyFrameWnd 构造式调用Create,产生主窗口。我们在Create 参数中指定的窗口类别是NULL, 于是MFC 根据窗口种类, 自行为我们注册一个名为"AfxFrameOrView42d" 的窗口类别。

  回到InitInstance 中继续执行ShowWindow,显示窗口。
  执行UpdateWindow,于是发出WM_PAINT。
  回到AfxWinMain,执行Run,进入消息循环。

程序开始运作:
  程序获得WM_PAINT 消息(藉由CWinApp::Run 中的::GetMessage 循环)。
  WM_PAINT 经由::DispatchMessage 送到窗口函数CWnd::DefWindowProc 中。

  CWnd::DefWindowProc 将消息绕行过消息映射表格(Message Map)。

  绕行过程中发现有吻合项目,于是调用项目中对应的函数。此函数是应用程序利用BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之间的宏设立起来的。

  标准消息的处理例程亦有标准命名,例如WM_PAINT 必然由OnPaint 处理。程序的死亡:

  使用者选按【File/Close】,于是发出WM_CLOSE。

  CMyFrameWnd 并没有设置WM_CLOSE 处理例程,于是交给预设之处理例程。
  预设函数对于WM_CLOSE 的处理方式是调用::DestroyWindow, 并因而发出WM_DESTROY。

  预设之WM_DESTROY 处理方式是调用::PostQuitMessage,因此发出WM_QUIT。
  CWinApp::Run 收到WM_QUIT 后会结束其内部之消息循环, 然后调用ExitInstance,这是CWinApp 的一个虚拟函数。

  如果CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所调用的就是CMyWinApp::ExitInstance,否则就是CWinApp::ExitInstance。

  最后回到AfxWinMain,执行AfxWinTerm,结束程序。

三、Document-View

1、Document

  Document 在MFC 的CDocument 里头被具体化。CDocument 本身并无任何具体数据,它只是提供一个空壳。当你开发自己的程序,应该从CDocument 衍生出一个属于自己的Document 类别,并且在类别中声明一些成员变量,用以承载(容纳)数据。然后再(至少)改写专门负责文件读写动作的Serialize 函数。应为他派生至CObject,所有它有CObject 所支持的一切性质,包括执行时期型别信息(RTTI)、动态生成(Dynamic Creation)、文件读写(Serialization)。

2、View

  View 负责描述Document中的资料,也是在在MFC 的CView 里头被具体化。它只是提供一个空壳。当你开发自己的程序,应该从CView 衍生出一个属于自己的View 类别,并且在类别中(至少)改写专门负责显示资料OnDraw 函数(针对屏幕)或OnPrint 函数(针对打印机)。由于CView 衍生自CWnd,所以它可以接收一般Windows 消息(如WM_SIZE、WM_PAINT 等等),又由于它也衍生自CCmdTarget,所以它可以接收来自菜单或工具列的WM_COMMAND 消息。

 3、Frame

 框架窗口在Document/View之上,主要管理UI。

4、 Document Template

  MFC 把Document/View/Frame 视为三位一体。其中用 Document Template来管理这个"三人组合"。MFC 有一个CDocTemplate 负责管理。

 

posted @ 2017-09-06 20:33  920101yz  Views(189)  Comments(0Edit  收藏  举报