按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
的派生类)派生一个相应的文档类。
…………………………………………………………Page 431……………………………………………………………
2。 为文档类添加成员变量。这些成员变量用来保存文档的数据,其
它对象 (如与文档相关联的视)直接或间接的访问这些成员变量来读取
或更新文档的数据。
3。 重载Serialize成员函数,实现文档数据的串行化。
如果您的应用程序只使用一种文档类型,那么,在创建应用程序工程
时,AppWizard已为我们完成了一部分工作。典型地,AppWizard为应
用程序框架生成一个CDocument类的派生类,在默认情况下该类的命
名依赖于工程的名称。然后,AppWizard在该文档类中重载了基类的
几个成员函数,包括OnNewDocument和Serialize等。但是,
AppWizard在这些重载函数中只是简单地调用基类的相应函数,您需
要根据自己的应用程序的需要来修改它们。
图8。6 示例程序Example的运行结果
8。3。2 把文档数据保存到成员变量中
在使用文档/视结构的应用程序中,我们通常使用文档类的成员变量
来保存文档的数据。并使其它的对象(如与文档相关联的视)可以访问
这些成员变量,从而实现了文档和其它对象(主要是视)的相互搭配使
用。
下面我们来看一个简单的例子。该示例程序运行时如图8。6所示。
1。 首先创建一个MFC AppWizard (exe)工程,并取名为Example。如
果需要了解如何使用AppWizard创建一个基于文档/视结构的多文档界
面应用程序框架,请参阅 “8。2。1使用AppWizard创建使用文档/视结
构的应用程序所需的步骤” 一节中的讲述。
…………………………………………………………Page 432……………………………………………………………
2。 在Workspace窗口的ClassView选项卡中展开Example classes,可
以看到AppWizard为Example程序生成的所有类。右击CExampleDoc
类,单击Add Member Variable。。。,在Variable Type框中输入成员
变量的类型CString,在Variable Declaration框中输入成员变量名
m_str。由于我们希望其它类的对象可以访问该成员变量,因此在
Access框中选择其访问类型为Public。单击 “OK”,Visual C++将
该成员变量的定义添加类的定义中。
再按照与上面的过程相同的方法,在类CExampleDoc中添加类型为
LOGFONT的公有成员变量m_lf。
我们也可以手动地将成员变量添加到类CExampleDoc的定义中。如下
面的步骤所示:
2'。 在Workspace窗口中的FileView选项卡中展开Example
files|Header Files。双击ExampleDoc。h,Visual C++将在代码编辑
窗口中打开文件ExampleDoc。h,这个文件包括了Example应用程序中
的文档类CExampleDoc的定义。
在其中的
// Attributes
public:
之后手工地输入
CString m_str;
LOGFONT m_lf;
您也许已经发现,在类CExampleDoc的定义中包括多个public块。事
实上,您可以把这些定义都放到同一个public块中,在定义中包括多
个public块只是为了区别开不同用途的公有成员。例如,在上面所示
的代码中,我们将成员变量m_str的定义放到Attributes块内;而如
果您是使用Add Member Variable。。。添加变量的话,Visual C++是将
它添加到Implementation块中。这只是为了便于程序的阅读和维护,
对于编译器而言,您将公有成员的定义放到哪一个public块中其结果
都是一样的,对于私有成员和保护成员也是一样。
3。 为了测试该程序中,我们在CExampleDoc的OnNewDocument成员变
量中为公有成员m_str赋以初值 “您好; 欢迎使用本程序 !”,并弹
出一个字体对话框让用户为该字符串选定字体。方法是使用下面的代
…………………………………………………………Page 433……………………………………………………………
码替换OnNewDocument的实现代码中的// TODO注释:
m_str=〃您好; 欢迎使用本程序!〃;
CFontDialog dlg;
dlg。GetCurrentFont(&m_lf);
// 将用户选定的字体信息填充到LOGFONT类型的结构m_lf中,以供视类使用
if(dlg。DoModal()==IDOK)
dlg。GetCurrentFont(&m_lf);
4。 再重复一下,在MFC应用程序中,文档类是和视类一起协作以完成
应用程序功能的。下面我们将为Example程序的视类CExampleView类
的OnDraw成员函数添加一些代码,以将文档类中的m_str成员变量的
内容显示到视的框架窗口中。关于视类的内容是在本章的 “8。4 生
成视” 一节中讲述的。在本节,为了使应用程序完整并且能够运
行,以反映我们对文档类所进行的一些操作,书中给出一些用于视类
的代码,并且,为了使章节的行文连贯和有重点,我们并不详细的讲
解这些代码。如果您还不是很了解视类的话,大可不必去在意这些代
码究竟都是怎样工作的,以及为什么要这样书写这些代码,把本书继
续看下去,这些代码都不会成其为问题。但若您现在很想了解这些内
容,那也不妨跳过去浏览一下 “8。4 生成视” 以及 “图形设备接
口”一章。
这里我们用下面的代码来替换类CExampleView的OnDraw成员函数。
// 获取当前客户区的大小
CRect rectClient;
GetClientRect(rectClient);
CSize sizeClient=rectClient。Size();
// 从文件中读取数据
CString str=pDoc…》m_str;
LOGFONT lf=pDoc…》m_lf;
// 使字体充满整个客户区
lf。lfHeight=sizeClient。cy;
lf。lfWidth=long(sizeClient。cx/str。GetLength());
…………………………………………………………Page 434……………………………………………………………
// 用当前字体信息生成CFont对象
CFont *pFont=new CFont;
pFont…》CreateFontIndirect(&lf);
// 改变当前所用字体,并保存旧字体
CFont *pOldFont=pDC…》SelectObject(pFont);
// 用新选定的字体绘制字符串 〃您好; 欢迎使用本程序!〃
CSize sizeTextExtent=pDC…》GetTextExtent(str);
pDC…》TextOut((sizeClient。cx…sizeTextExtent。cx)/2;
(sizeClient。cy…sizeTextExtent。cy)/2;
str);
// 恢复系统默认字体
pDC…》SelectObject(pOldFont);
在上面的示例程序中,我们在文档类中定义了两个公有的成员变量
m_str和m_lf,然后在视类的OnDraw成员函数中访问了这两个成员变
量,通过这些变量从文档中获取所要显示的字符串和所使用的字体。
很多时候我们常使用的是另外一种方法,即把成员变量定义为私有或
保护成员,然后添加存取该成员变量的函数。如下面的代码所示:
protected:
CString m_str;
public:
CString GetStr()
{
CString *pStr=new CString;
*pStr=m_str;
return *pStr;
}
这样的好处是可以防止数据成员被从类外部修改,从而维护了类中数
…………………………………………………………Page 435……………………………………………………………
据的安全。
l 注意:
l 不象很多资料上所说的那样,在GetStr函数中使用下面的代码,
并不能保证类中的保护成员绝对不会被从外部修改:
l CString GetStr()
l {
l return m_str;
l }
这时,如果类的使用者在外部使用了如下面的语句所示的强
制类型转换,
l