一、C++的重要性质
二、MFC六大关键技术
消息的路线图:
三、MFC五大群组
1、General Purpose classes:提供字符串类、数据处理类(如数组与链表),异常情况处理类、文件类等。
(1)Object:绝大部分类库,往往以一个或两个类,作为其他绝大部分类的基础。CObject 是万类之首,凡类派生自CObject者,得以继承数个面向对象重要性质,包括RTTI(运行时类型识别)、Persistence(对象保存)、Dynamic Creation(动态创建)、Diagnostic(错误诊断)。其中,“对象保存”有牵扯到CArch
ive,“诊断”又牵扯到CDumpContext,“运行时类别识别”以及“动态创建”又牵扯到CRuntimeClass。
(2)数据处理类(collection classes)
所谓collection,意指用来管理一“群”对象或标准类型的数据。这些类像是Array或List或Map等等,都内含针对元素的“加入”或“删除”或“巡访”等成员函数。Array(数组)List(链表)是数据结构。Map视之为表格由两两对象的键值所构成,使很容易由某一对象得知成对的另一对象;
collection classes
(3)杂项类
CRect 、CSize、CPoint、CTime(GetCurrentTime、 时间数据格式化、抽取特定字段(时、分、秒)等)对于+、-、+=、-+等运算符都进行了重载操作。
、CTimeSpan以秒数表示时间,通常用于计时码表。有包括把秒数转换为日、时、分秒等、CString用来处理字符串。支持标准的运算符,如:=、+=、<和>。
(4)异常处理类(exception handling classes)
2、Windows API classes:用来封装Windows API,例如窗口类、对话框类、DC类等。
(1)CWinThread:代表MFC程序中的一个线程。自从3.0版之后,所有的MFC类就都已经是thread-safe了。SDK程序中标准的消息循环已经被封装在这一类之中(第六章)。
(2)CWinApp:代表你的整个MFC应用程序。此类派生自CWinThread:要知道,任何32位Windows程序至少由一个线程构成。CWinApp内含有用的成员变量如:m_szExeName,放置执行文件名,以及有用的成员函数如PrcoessShellCommand,处理命令行选项。
(3)CWnd:所有窗口,不论是主框窗口、子框窗口、对话框、控件view窗口,都有一个对应的C++类,你可以想象“窗口handle”和“C++对象”结盟。这些C++类统统派生自CWnd,也就是说,凡派生自CWnd的类才能收到WM_窗口消息(WM_COMMAND除外)。
所谓“窗口handle”和“C++对象”结盟,实际上是CWind对象有一个成员变量m_hWnd,就放着对应的窗口handle.所以,只要你手上有一个CWnd对象或CWnd对象指针,就可以轻易获得其窗口handle:HWND hwnd=pWnd->m_hWnd;
(4)CCmdTarget:CWnd的分类。派生自它,类才能够处理命令WM_COMMAND。这个类是消息映射以及命令消息传递的大部分关键,(第九章)
(5)GDI类、DC类、Menu类。
3、Application framework classes:组成应用程序骨干类,即此组类,包括Dcoument/View、消息泵、消息映射、消息传递、动态创建、文件读写等等。
Document/View的观念是希望把数据的本体和数据的显示分开处理。由于文件产生之际,必须动态创建Document/View/Frame三种对象,所以又必须由所谓的Document Template管理之。
(1)CDocTemplate、CSingleDocTemplate、CMultiDocTemplate:Document Template扮演黏胶的角色,把Document和View和其Frame(外框窗口)胶黏在一块儿。CSingleDocTemplate一次只支持一种文件类型,CMultiDocTemplate可同时支持多种文件类型。注意,这和MDI程序或SDI程序无关,换句话说,MDI程序也可以使用CSingleDocTemplate,SDI程序也可以使用CMultiDocTemplate
(2)CDocument:当你为自己的程序由CDocument派生出一个子类后,应该在其中加上成员变量,以容纳文件数据:并加上成员函数,负责修改文件内容以及读写文件。读写文件由虚函数Serialize负责。
(3)CWiew:此类负责将文件内容呈现到显示装置上:也许是屏幕,也许是打印机。文件内容的呈现由虚函数OnDraw负责。由于这个类实际上就是你在屏幕上所看到的窗口(外再罩一个外框窗口)。负责使用者输入的第一线服务。
4、High level abstractions:包括工具栏、状态栏、拆分窗口、滚动窗口等等。
视觉性UI对象属于此类,例如工具栏CToolBar、状态栏CStatusBar、对话框列CDialogBar。加强型的View也属此类,如可滚动的ScrollView、以对话框为基础的CFormView、小型文字编辑器CEditView、树状结构的CTreeView,支持RTF文件格式的CRichEditView等等。
5、operation system extensions:包括OLE、ODBC、DAO、MAPI、WinSock、ISAPI等等。
Afx全局函数
MFC之中得以存在有不属于任何类的全局函数,它们统统在函数名称开头冠以Afx。
函数名称 说明
AfxWinInit 被WinMain(由MFC提供)调用的一个函数,用做MFC GUI程序初始化的一部分,(6章“AfxWinInit——AFX内部初始化操作”写一个MFC Console程序就得自行调用此函数)
AfxBeginThread 开始一个新的线程(14章p560)
AfxEndThread 结束一个旧的线程(14章p560)
AfxFormatString1 类似printf一般地将字符串格式化
AfxFormatString2 类似printf一般地将字符串格式化
AfxMessageBox 类似Windows API函数MessageBox
AfxOutputDebugString 将字符输往除错装置p691
AfxGetApp 获得application object(CWinApp派生对象)的指针
AfxGetMainWnd 获得程序的instance handle
AfxGetInstance 获得程序的instance handle
AfxRegisterClass 以自定义的WNDCLASS注册窗口类(如果MFC提供的数个窗口类不能满足你)
MFC宏(macros)
CObject和CRuntimeClass之中封装了数个所谓的object services,包括“取得运行时的类信息”(RTTI)、Serialization(文件读写)、动态产生对象...等
等。所有派生自CObject的类,都继承这些机能。
取得运行时的类信息(RTTI),使你能够决定一个运行时的对象的类型信息,这样的能力在你需要对函数参数做一些额外的类型检验,或是当你要针对对象属
于某种类而进行特别的操作时,分外有用。
Serialization是指将对象内容写到文件中,或从文件中读出。如此一来对象的生命就可以在程序之后还延续下去,而在程序重新激活之后,再被读入。这样
的对象可说是“persistent”
所谓动态的对象创建(Dynamic object creation),使你得以在运行时产生一个特定的对象。例如document 、view、和frame对象就都必须支持动态对象创
建,因为framework需要在运行时产生他们。(第8章)
宏名称 提供机能 出现章节
DECLARE_DYNAMIC 运行时类信息 第3章、第8章
IMPLEMENT_DYNAMIC 运行时类信息 第3章、第8章
DECLARE_DYNCREATE 动态创建 第3章、第8章
IMPLEMENT_DYNCREATE 动态创建 第3章、第8章
MFC的消息映射(Message Mapping)与命令传递(Command Routing)两个特性。这两个性质由以下这些MFC宏完成:
宏名称 提供机能 出现章节
DECLARE_MESSAGE_MAP 声明消息映射表数据结构 第3章、第9章
BEGIN_MESSAGE_MAP 开始消息映射表的建立 第3章、第9章
ON_COMMAND 增加消息映射表中的项目 第3章、第9章
ON_CONTROL 增加消息映射表中的项目 本书未举例
ON_MESSAGE 增加消息映射表中的项目 ???
ON_OLECMD 增加消息映射表中的项目 本书未举例
ON_REGISTERED_MESSAGE 增加消息映射表中的项目 本书未举例
ON_REGISTERED_THREAD_MESSAGE 增加消息映射表中的项目 本书未举例
ON_THREAD_MESSAGE 增加消息映射表中的项目 本书未举例
ON_THREAD_MESSAGE 增加消息映射表中的项目 本书未举例
ON_UPDATE_COMMAND_UI 增加消息映射表中的项目 第3章、第9章
END_MESSAGE_MAP 结束消息映射表的键值 第3章、第9章
MFC数据类型
BOOL Boolean值(布尔值,不是TRUE就是FALSE)
BSTR 32-bit字符指针
BYTE 8-bit整数,未带正负号
COLORREF 32-bit数值,代表一个颜色值
DWORD 32-bit整数,未带正负号
LONG 32-bit整数,带正负号
LPARAM 32-bit数值,作为窗口函数或callback函数的一个参数
LPCSTR 32-bit指针,指向一个常数字符串
LPSTR 32-bit指针,指向一个字符串
LPCTSTR 32-bit指针,指向一个常数字符串。此字符串可移植到Unicode和DBCS(双字节字集)
LPTSTR 32-bit指针,指向一个字符串。此字符串可移植到Unicode和DBCS(双字节字集)
LPVOID 32-bit指针,指向一个未指定类型的数据
LPRESULT 32-bit数值,作为窗口函数或callback函数的返回值
UINT 在Win16中是一个16-bit未带正负号整数,在Win32中是一个32bit未带正负号整数
WNDPROC 32-bit指针,指向一个窗口函数
WORD 16-bit整数,未带正负号
WPARAM 窗口函数的callback函数的一个参数。在Win16中是16bits,在Win32中是32bits
下面这些是MFC独特的数据类型:
POSITION 一个数值,代表collection对象(例如数组或链表)中的元素位置。常使用于MFC colleciton classes
LPCRECT 32-bit指针,指向一个不变的RECT结构
四、MFC程序的生死因果
-
一、WinMain 由MFC提供
二、RegisterClass包装于AfxWinInit中
三、CreateWindow应该在CWinApp::InitInstance中调用
四、GetMessage/DispatchMessage包装在CWinApp::Run中
五、WindowProcedure由MFC提供
六、WindowAPIs包装在MFC各类中
七、Dynamic Creation,Serialization,Message Mapping,Message Roution.
MFC需要的函数库
1、Windows C Runtime函数库(VC++5)
LiBC.LIB 898826字节 CRuntime函数库的静态链接版本
MSVCRT.LIB 510000字节 CRuntime函数库的动态链接版本
MSVCRTD.LIB 803418字节 Debug方式
2、DLL Import 函数库(VC++5)
GDI32.LIB 307520字节 for GDI32.DLL
USER32.LIB 517018字节 for USER32.DLL
KERNEL32.LIB 635638字节 for KERNEL32.DLL
3、MFC函数库(AFX函数库)(VC++5,MFC 4.2)
MFC42.LIB MFC42.DLL
MFC42D.LIB MFC42D.DLL
MFCS42.LIB MFCS42.DLL
MFCS42D.LIB MFCS42D.DLL
MFCN42D.LIB MFCN42D.DLL
MFCD42D.LIB MFCD42D.DLL
MFCO42D.LIB MFCO42D.DLL
(1)STDAFX.H:这个文件用来作为Precompiled header file ,其内只是载入其他的MFC头文件。应用程序通常会准备自己的STDAFX.H,有时载入AFXWIN.H
(2)AFXWIN.H:每一个Windows MFC程序都必须载入它,因为它以及它所载入的文件声明了所有的MFC类。此文件内含AFX.H,后者又载入AFXVER_.H,后者又载入AFXV_W32.H,后者又载入WINDOWS.H
(3)AFXEXT.H:凡使用工具栏、状态栏、的程序必须载入这个文件。
(4)AFXDLGS.H:凡使用通用型对话框(Common Dialog)的MFC程序需载入此文件,其内部载入COMMDLG.H
(5)AFXCMN.H:凡使用Windows9x新增的通用型控件(Common Control)之MFC程序需载入此文件。
(6)AFXCOLL.H:凡使用Collections Classes(用以处理数据结构如数组、链表)之程序必须载入此文件。
(7)AFXDLLX.H:凡MFC extension DLLs均需载入此文件。
(8)AFXRES.H:MFC程序的RC文件必须载入此文件。MFC对于标准资源(例如File、Edit等菜单项目)的ID都有默认值,定义此文件中。
所有MFC都稳健爱你均置于\MSVC\MFC\INCLUDE中。Precompiled Header 就是将.H文件第一次编译后的结果存储起来,第二次再编译时就可以直接从磁盘中取出来