友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
深入浅出MFC第2版(PDF格式)-第46部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
330
…………………………………………………………Page 393……………………………………………………………
第5章 總觀Application Framework
List 或Map 等等,都内含针对元素的「加入」或「删除」或「巡访」等成员函数。Array
(数组)和List (串行)是数据结构这门课程的重头戏,大家比较熟知,Map (可视之
为表格)则是由成双成对的两两对象所构成,使你很容易由某一对象得知成对的另一物
件;换句话说一个对象是另一个对象的键值(key )。例如,你可以使用String…to…String
Map ,管理一个「电话…人名」数据库;或者使用Word…to…Ptr Map ,以16 位数值做为
一个指针的键值。
最令人侧目的是,由于这些类别都支持Serialization,一整个数组或串行或表格可以单一
一进程序代码就写到文件中(或从文件读出)。第8章的Scribble Step1 范例程序中你就会
看到它的便利。
MFC 支持的collection classes 有:
CObject
CObject
CArray (template) CList (template) CMap (template)
CArray (template) CList (template) CMap (template)
CByteArray CPtrList CMapWordToPtr
CByteArray CMapWordToPtr
CDWordArray CObList CMapPtrToWord
CDWordArray CObList CMapPtrToWord
CObArray CStringList CMapPtrToPtr
CObArray CStringList CMapPtrToPtr
CPtrArray Lists of user types CMapWordToOb
CPtrArray Lists of user types CMapWordToOb
CStringArray CMapStringToPtr
CStringArray Typed Template Collections CMapStringToPtr
CUIntArray CTypedPtrArray CMapStringToOb
CUIntArray CTypedPtrArray CMapStringToOb
CWordArray CTypedPtrList CMapStringToString
CWordArray CTypedPtrList CMapStringToString
Arrays of user types CTypedPtrMap Maps of user types
Arrays of user types CTypedPtrMap Maps of user types
杂项类别
■ CRect 封装Windows 的RECT 结构。这个类别在Windows 环境中特别有用,
因为CRect 常常被用作MFC 类别成员函数的参数。
■ CSize 封装Windows 的SIZE 结构。
■ CPoint 封装Windows 的POINT 结构。这个类别在Windows 环境中特别有用,
331
…………………………………………………………Page 394……………………………………………………………
第篇 湷觥 FC 程式設計
因为CPoint 常常被用作MFC 类别成员函数的参数。
■ CTime 表现绝对时间, 提供许多成员函数, 包括取得目前时间( static
GetCurrentTime)、将时间资料格式化、抽取特定字段(时、分、秒)等等。它
对于+ 、…、+= 、…+ 等运算子都做了多载动作。
■ CTimeSpan 以秒数表现时间,通常用于计时码表。提供许多成员函数,包括把
秒数转换为日、时、分、秒等等。
■ CString 用来处理字符串。支持标准的运算子如= 、+= 、《 和》 。
异常处理类别 (exception handling classes)
所谓异常情况(exception ),是发生在你的程序执行时期的不正常情况,像是文件打不
开、内存不足、写入失败等等等。我曾经在第2章最后面介绍过异常处理的观念及相
关的MFC 类别,并在第4章「Exception Handling」一节介绍过一个简单的例子。与「异
常处理」有关的MFC 类别一共有以下11 种:
CException
CException
CArchiveException
CArchiveException
CDaoException
CDaoException
CDBException
CDBException
CFileException
CFileException
CMemoryException
CMemoryException
CNotSupportedException
CNotSupportedException
COleException
COleException
COleDispatchException
COleDispatchException
CResourceException
CResourceException
CUserException
CUserException
332
…………………………………………………………Page 395……………………………………………………………
第5章 總觀Application Framework
Windows API classes
这是MFC 声名最著的一群类别。如果你去看看源代码,就会看到这些类别的成员函数
所对应的各个Windows API 函数。
■ CWinThread 代表MFC 程序中的一个执行线程。自从3。0 版之后,所有的MFC
类别就都已经是thread…safe 了。SDK 程序中标准的消息循环已经被封装在此
一类别之中(你会在第6章看到我如何把这一部份开膛剖肚)。
■ CWinApp 代表你的整个MFC 应用程序。此类别衍生自CWinThread;要知
道,任何32 位Windows 程序至少由一个执行线程构成。CWinApp 内含有用
的成员变量如m_szExeName, 放置执行档档名, 以及有用的成员函数如
ProcessShellmand,处理命令列选项。
■ CWnd 所有窗口,不论是主框窗口、子框窗口、对话框、控制组件、view 视
窗,都有一个对应的C++ 类别,你可以想象「窗口handle 」和「C++ 对象」
结盟。这些C++ 类别统统衍生自CWnd,也就是说,凡衍生自CWnd 之类别才
能收到WM_ 窗口消息(WM_MAND 除外)。
所谓「窗口handle 」和「C++ 对象」结盟,实际上是CWnd 对象有一个成员变
数m_hWnd ,就放着对应的窗口handle 。所以,只要你手上有一个CWnd 对象
或CWnd 对象指针,就可以轻易获得其窗口handle:
HWND hWnd = pWnd…》m_hWnd;
■ CCmdTarget CWnd 的父类别。衍生自它, 类别才能够处理命令消息
WM_MAND。这个类别是消息映射以及命令消息绕行的大部份关键,我将
在第9章推敲这两大神秘技术。
■ GDI 类别、DC 类别、Menu 类别。
333
…………………………………………………………Page 396……………………………………………………………
第篇 湷觥 FC 程式設計
Application framework classes
这一部份最为人认知的便是Document/View ,这也是使MFC 跻身application framework
的关键。Document/View 的观念是希望把资料的本体,和资料的显像分开处理。由于文
件产生之际,必须动态生成Document/View/Frame 三种对象,所以又必须有所谓的
Document Template 管理之。
■ CDocTemplate、CSingleDocTemplate、CMultiDocTemplate Document Template 扮演
黏胶的角色,把Document 和View 和其Frame (外框窗口)胶黏在一块儿。
■ CSingleDocTemplate 一次只支持一种文件类型,CMultiDocTemplate 可同时支持多
种文件类型。注意,这和MDI 程序或SDI 程序无关,换句话说,MDI 程序
也可以使用CSingleDocTemplate,SDI 程序也可以使用CMultiDocTemplate 。
但是,逐渐地,MDI 这个字眼与它原来的意义有了一些出入(要知道,这个字眼早
在SDK 时代即有了)。因此,你可能会看到有些书籍这么说:MDI 程序使用
CMultiDocTemplate,SDI 程序使用CSingleDocTemplate 。
■ CDocument 当你为自己的程序由CDocument 衍生出一个子类别后,应该在其
中加上成员变量,以容纳文件资料;并加上成员函数,负责修改文件内容以及
读写档。读写文件由虚拟函数Serialize 负责。第8章的Scribble Step1 范例程序
有极佳的示范。
■ CView 此类别负责将文件内容呈现到显示装置上:也许是屏幕,也许是打印
机。文件内容的呈现由虚拟函数OnDraw 负责。由于这个类别实际上就是你在
屏幕上所看到的窗口(外再罩一个外框窗口),所以它也负责使用者输入的第
一线服务。例如第8章的Scribble Step1 范例,其View 类别便处理了鼠标的
按键动作。
High level abstractions
视觉性UI 对象属于此类,例如工具栏CToolBar、状态列CStatusBar、对话框列
CDialogBar。加强型的View 也属此类,如可卷动的ScrollView 、以对话框为基础的
334
…………………………………………………………Page 397……………………………………………………………
第5章 總觀Application Framework
CFormView、小型文字编辑器CEditView、树状结构的CTreeView,支持RTF 文件格式
的CRichEditView 等等。
Afx 全域函数
还记得吧,C++ 并不是纯种的对象导向语言(SmallTalk 和Java 才是)。所以,MFC
之中得以存在有不属于任何类别的全域函数,它们统统在函数名称开头冠以Afx 。
下面是几个常见的Afx 全域函数:
函数名称 说明
AfxWinInit 被WinMain (由MFC 提供)调用的一个函数,用做MFC GUI
程序初始化的一部份,请看第6章的「AfxWinInit AFX 内部
初始化动作」一节。如果你写一个MFC console 程序,就得
自行调用此函数(请参考Visual C++ 所附之Tear 范例程序)。
AfxBeginThread 开始一个新的执行线程(请看第14 章,# 756 页)。
AfxEndThread 结束一个旧的执行线程(请看第14 章,# 756 页)。
AfxFormatString1 类似printf 一般地将字符串格式化。
AfxFormatString2 类似printf 一般地将字符串格式化。
AfxMessageBox 类似Windows API 函数MessageBox 。
AfxOutputDebugString 将字符串输往除错装置(请参考附录D ,# 924 页)。
AfxGetApp 取得application object (CWinApp 衍生对象)的指针。
AfxGetMainWnd 取得程序主窗口的指针。
AfxGetInstance 取得程序的instance handle 。
AfxRegisterClass 以自定的WNDCLASS 注册窗口类别(如果MFC 提供的数个
窗口类别不能满足你的话)。
MFC 宏 (macros)
CObject 和CRuntimeClass 之中封装了数个所谓的object services ,包括「取得执行时期
的类别信息」(RTTI )、Serialization (文件读写)、动态产生对象。。。等等。所有衍生自CObject
335
…………………………………………………………Page 398……………………………………………………………
第篇 湷觥 FC 程式設計
的类别,都继承这些机能。我想你对这些名词及其代表的意义已经不再陌生…如果你没
有错过第3章的「MFC 六大技术仿真」的话。
■ 取得执行时期的类别信息(RTTI ),使你能够决定一个执行时期的对象的类别
信息,这样的能力在你需要对函数参数做一些额外的类型检验,或是当你要针
对对象属于某种类别而做特别的动作时,份外有用。
■ Serialization 是指将对象内容写到文件中,或从文件中读出。如此一来对象的
生命就可以在程序结束之后还延续下去,而在程序重新激活之后,再被读入。
这样的对象可说是〃persistent〃 (永续存在)。
■ 所谓动态的对象生成(Dynamic object creation ),使你得以在执行时期产生一
个特定的对象。例如document 、view 、和frame 对象就都必须支持动态对象
生成,因为framework 需要在执行时期产生它们(第8章有更详细的说明)。
此外,OLE 常常需要在执行时期做对象的动态生成动作。例如一个OLE server 程序必
须能够动态产生OLE items ,用以反应OLE client 的需求。
MFC 针对上述这些机能,准备了一些宏,让程序能够很方便地继承并实作出上述四大
机能。这些宏包括:
宏名称 提供机能 出现章节
DECLARE_DYNAMIC 执行时期类别信息 第3章、第8章
IMPLEMENT_DYNAMIC 执行时期类别信息 第3章、第8章
DECLARE_DYNCREATE 动态生成 第3章、第8章
IMPLEMENT_DYNCREATE 动态生成 第3章、第8章
DECLARE_SERIAL 对象内容的文件读写 第3章、第8章
IMPLEMENT_SERIAL 对象内容的文件读写 第3章、第8章
DECLARE_OLECREATE OLE 对象的动态生成 不在本书范围之内
IMPLEMENT_OLECREATE OLE 对象的动态生成 不在本书范围之内
336
…………………………………………………………Page 399……………………………………………………………
第5章 總觀Application Framework
我也已经在第3章提过MFC 的消息映射(Message Mapping)与命令绕行(mand
Routing)两个特性。这两个性质系由以下这些MFC 宏完成:
宏名称 提供机能 出现章节
DECLARE_MESSAGE_MAP 声明消息映射表数据结构 第3章、第9章
BEGIN_MESSAGE_MAP 开始消息映射表的建置 第3章、第9章
ON_MAND 增加消息映射表中的项目 第3章、第9章
ON_CONTROL 增加消息映射表中的项目 本书未举例
ON_MESSAGE 增加消息映射表中的项目 ???
ON_OLECMD 增加消息映射表中的项目 本书未举例
ON_REGISTERED_MESSAGE 增加消息映射表中的项目 本书未举例
ON_REGISTERED_THREAD_ 增加消息映射表中的项目 本书未举例
MESSAGE
ON_THREAD_MESSAGE 增加消息映射表中的项目 本书未举例
ON_UPDATE_MAND_UI 增加消息映射表中的项目
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!