学习MFC(1)一些基础知识的详细记录

1.Windows程序的生与死(把好多WM打成了VM…。。。)
①.程序初始化过程中调用CreateWindow,为程序建立一个窗口,作为程序的屏幕舞台。CreateWindow产生窗口之后会送出VM_CREATE直接给窗口函数,后者于是可以在此时做些初始化操作(例如配置内存、打开文件、读初始数据…)。
②.在程序活着的过程中,不断以GetMessage从消息队列中抓取消息。如果这个消息是VM_QUIT,GetMessage会传回0而结束while循环,从而结束整个程序。
③.DispatchMessage通过Windows USER模块的协助与监督,把消息分派至窗口函数。消息将在该处被判别并处理。
④.程序不断进行②和③的操作。
⑤.当使用者按下系统菜单中的Close命令项时,系统送出VM_CLOSE.通常程序的窗口函数不拦截此消息,于是DefWindowProc处理它。
⑥.DefWindowProc收到VM_CLOSE后,调用DestroyWindow把窗口清除。DestoryWindow本身又会送出VM_DESTROY。
⑦.程序对VM_DESTROY的标准反应是调用PostQuitMessage。
⑧.PostQuitMessage没什么其他操作,就只送出VM_QUIT消息,准备让消息循环中的GetMessage取得,如步骤②,结束消息循环。
2.MFC的两个非常重要的虚函数:与document有关的Serialize函数和与View有关的OnDraw函数。你应该在自己的CMyDoc和CMyView中改写这两个虚函数。虚函数是C++语言的多态性以及动态绑定的关键。
3.关于MFC的最基本的类结构的图片。这张图片上是MFC的最核心的几个类的继承关系。
在这里插入图片描述

4.AppWizard、Visual C++ IDE和Resource Editor之间的作用关系,以使最终形成一个应用程序。
在这里插入图片描述

5.新建一个MFC程序,需要重点关注的几个类,因为这几个类后面添加大量的代码,相对于它们,其他的那些类啊,啥的。就不怎么需要修改。
在这里插入图片描述

6.C++基础不好,学习MFC是个很难的事。以下是《深入浅出MFC》的配图,形象的说明了这个东西。
在这里插入图片描述

《深入浅出MFC》这本书的作用就是:
在这里插入图片描述
7.MFC的每个project都有一个DSW文件和DSP文件。如果在下次需要继续工作的时候,在[File/Open]对话框中打开DSW文件就可以了。DSP是Developer Studio Project的缩写,DSW是Developer Studio Workspace的缩写。Workspace是VC++集成开发环境的一个维护档,可以把与project有关的IDE环境设定都记录下来。
8. 基本上可以说,Application Framework是一个完整的程序模型,具备标准应用软件所需的一切基本功能,像是文件存取、打印预览、数据交换…,以及这些功能的使用接口(工具栏、状态栏、菜单、对话框)。如果更以术语来说,Application Framework就是由一整组合作无间的“对象”结构起来的大模型。不不,当它还没有与你的程序产生火花的时候,它还只是有形无体,应该说是一组合作无间的“类”结构起来的大模型。
9.MFC把有着相当固定行为的WinMain内部操作封装在CWinApp中,把有着相当固定行为的WndProc内部操作封装在CFrameWnd中。这就解释了MFC程序里面的关于Windows程序的两个最重要的函数在哪里。这么一来,CWinApp代表程序主体,CFrameWnd代表一个主框窗口。
10.MFC中的消息分为三大类:标准Windows消息,命令消息,通知消息。
11.MFC程序的诞生:
①Application object产生,内存于是获得配置,初值亦设立了。
②AfxWinMain执行AfxWinInit,后者又调用AfxInitThread,把消息队列尽量加大到96.
③AfxWinMain执行InitApplication.这是CWinApp的虚函数,但是我们通常不改写它。
④AfxWinMain执行InitInstance.这是CWinApp的虚函数,我们必须改写它。
⑤CMyWinApp::InitInstance “new”了一个CMyFrameWnd对象。
⑥CMyFrameWnd构造函数调用Create,产生主窗口。我们在create参数中指定的窗口类是NULL,于是MFC根据窗口种类,自行为我们注册一个名为”AfxFrameOrView42d”的窗口类。
⑦回到InitInstance中继续执行ShowWindow,显示窗口。
⑧执行UpdateWindow,于是发出VM_PAINT。
⑨回到AfxWinMain,执行Run,进入消息循环。
12.程序开始执行:
①程序获得VM_PAINT消息(藉由CWinApp::Run中的::GetMessage循环获得)。
②VM_PAINT经由::DisPatchMessage送到窗口函数CWnd::DefWindowProc中。
③CWnd::DefWindowProc将消息传递给消息映射表格(Message Map)。
④传递过程中发现有相符项目,于是调用项目中对应的函数。此函数是应用程序利用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间的宏设立起来的。
⑤标准消息的处理程序亦有标准命名,例如VM_PAINT必然由OnPaint处理。
13.程序的死亡:
①使用者点击[File/Close],于是发出VM_CLOSE.
②CMyFrameWnd并没有设置VM_CLOSE处理程序,于是交给默认的处理程序。
③默认函数对于VM_CLOSE的处理方式是调用::DestroyWindow,并因而发出VM_DESTROY.
④默认的VM_DESTROY处理方式是调用::PostQuitMessage,因此发出VM_QUIT.
⑤CWinApp::Run收到VM_QUIT后会结束其内部之消息循环,然后调用ExitInstance,这是CWinApp的一个虚拟函数。
⑥如果CMyWinApp改写了ExitInstance,那么CWinApp::Run所调用的就是CMyWinApp::ExitInstance,否则就是CWinApp::ExitInstance.
⑦最后回到AfxWinMain,执行AfxWinTerm,结束程序。
14.要把某个函数用作callback函数,就必须告诉C++编译器,不要让this指针作为该函数的最后一个参数。采用以下两个办法可以做到这一点:
①不要使用类的成员函数(也就是说,要使用全局函数)作为callback函数。
②使用static成员函数。也就是在函数前面加上static修饰词。
(C++中,static成员函数的特性是,即使对象还没有产生,static成员已经存在。函数或变量都是如此。也就是说,凡是声明为static的东西都不和对象结合在一起,它们是类的一部分,不属于对象。)
15.Document/View/Frame的产生。
在这里插入图片描述

16.Document和View之间的关系。
①CWinApp拥有一个对象指针:CDocManager*m_pDocManager.
②CDocManager拥有一个指针链表CPtrList m_templateList,用来维护一系列的Document Template.一个程序若支持两“种”文件类型,就应该由两份Document Templates,应用程序应该在CMyWinApp::InitInstance中以AddDocTemplate将这些Document Templates加入到由CDocManager所维护的链表之中。
③CDocTemplate拥有三个成员变量,分别持有Document、View、Frame的CRuntimeClass指针,另有一个成员变量m_nIDResource,用来表示此Document显现时应该采用的UI对象。这四份数据应该在CMyWinApp::InitInstance函数构造CDocTemplate时指定之,成为构造函数的参数。当使用者欲打开一份文件时,CDocTemplate即可借由Document/View/Frame之CRuntimeClass指针进行动态创建。
④CDocument有一个成员变量CDocTemplate*m_pDocTemplate,回指其Document Template:另有一个成员变量CPtrList m_viewList,表示它可以同时维护一系列的Views.
⑤CFrameWnd有一个成员变量CView*m_pViewActive,指向当前活动的View.
⑥CView有一个成员变量CDocument*m_pDocument,指向相关的Document.
17.基于对话框、单文档、多文档的MFC程序的区别。(网上的一个答案)
①对话框框架程序对于控件组成的界面有更好的包装,适应于界面通过很多控件呈现的简单程序。CDialog 类提供管理对话框的接口,Visual C++ 对话框编辑器使设计对话框和创建它们的对话框模板资源更为容易,代码向导则简化了在对话框中初始化和验证控件的过程和收集用户输入的值的过程。
②文档/视图框架对于菜单、工具条和状态栏等UI元素有更好的包装,适应于需要对文件进行较多处理的应用。MFC 将数据管理分成文档类和视图类。文档存储数据和管理数据的打印,并协调更新多个数据视图。视图显示数据并管理用户与数据之间的交互,包括选择和编辑。在此模型中,MFC 文档对象将数据读入或写入永久存储区。该文档还可能提供到数据所驻留的任何位置(如在数据库中)的接口。一个单独的视图对象可管理数据显示,包括从在窗口中呈现数据到用户选择和数据编辑。该视图从文档获取显示数据,并将任何数据更改传递回文档。MFC 文档/视图结构使支持多视图、多文档类型、拆分窗口和其他有价值的用户界面功能变得容易。
18.CDocument简单的说是一个负责处理数据的类。CView是为了数据的表现而设计的。View还负责程序与使用者之间的交谈接口。使用者对数据的编辑、修改都需依赖窗口上的鼠标与键盘操作才得以完成,这些消息都将由View接受后再通知Document.
19.有关文件读写的操作在CDocument的Serialize函数中进行。有关画面显示的操作在CView中的OnPaint或OnDraw函数中进行。
20.MFC的Document/View的结构希望更把程序员的精力放在真正的数据结构设计以及真正的数据显示操作上,而不要花费时间在模块的沟通或消息的流动传递上。
21.一般而言,程序每打开一份文件,就应该产生三份对象。一份Document对象,一份View对象,一份CMDIChildWnd对象,这三份对象由一个所谓的Document Template对象来管理。让这三份对象产生关系的关键在于CMultiDocTemplate.
22.文件的读写,需要改写Serialize函数使之符合个人需求。除了读写,数据的显示也是必要的操作,数据的接受编辑也是必要的操作。两者都由View负责。使用者对Document的任何编辑操作都必须通过Document Frame窗口,消息随后传到CView。
①当Document Frame窗口收到WM_PAINT,窗口内的View的OnPaint函数会被调用,OnPaint又调用OnDraw.所以为了显示数据,我们必须改写OnDraw.至于OnPaint,主要做的是“只输出到屏幕而不是到打印机”的操作。
②为了接受编辑操作,我们必须在View类中接受鼠标或键盘消息并处理之。
23.VS2019 MFC使用的是UTF16-LE 编码格式。
在这里插入图片描述

原创文章 77 获赞 4 访问量 9016

猜你喜欢

转载自blog.csdn.net/weixin_40007143/article/details/106055921