按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
现在就可以编译和生成该应用程序了。图7。7为应用程序VideoPlayer
播放VCD文件时的效果。
图7。 7 应用程序VideoPlayer播放VCD文件时的运行效果
l 技巧:
l 从上面的示例程序可以看出,ActiveMovie控件提供了非常完善的
音频和视频媒体文件的回放功能。它能够支持多种文件格式,从
最常见的WAV文件和AVI文件到使用MPEG压缩格式的VCD视频文件,
都可以正常的进行播放。因此,若正在编写的应用程序需要提供
多媒体支持,那么使用ActiveMovie是一个很好的主意。事实上,
很多优秀的多媒体应用程序,其内部的多媒体回放就是使用
ActiveMovie来实现的。只要精心的设计应用程序的用户界面,我
…………………………………………………………Page 425……………………………………………………………
们可以把一切 “隐藏”得滴水不漏。而且,在Windows 95/98和
Windows NT的最新版本中,ActiveMovie控件已作为操作系统的一
部分来提供。即使用户的系统中没有安装ActiveMovie控件,
Microsoft的许可协议也允许在你的应用程序的发行包中发布
ActiveMovie的运行时文件。充分的使用各种优秀的第三方
ActiveX控件,可使不费力的使用你的应用程序增色不少,这也就
是ActiveX控件本身的一个魅力之所在。
…………………………………………………………Page 426……………………………………………………………
第八章 文档 视结构
/
文档/视结构是在Visual C++中使用MFC开发基于文档的应用程序的基
本框架,在这个框架中,数据的维护及其显示是分别由两个不同,但
又彼此紧密相关的对象——文档和视负责的。文档/视结构在很多场
合与传统的编程方式相比要更有利于这一类应用程序的编写。
本章介绍Visual C++中的文档/视结构。这是一个相对比较复杂的课
题,所涉及的内容也比较广泛,具有来说有以下一些:
l 文档/视结构以及这种结构以编程带来的便利之处
l 是否使用文档/视结构的考虑
l 使用AppWizard创建基于文档/视结构的框架应用程序
l 使用文档类
在文档类的成员变量中保存文档数据
串行化文档数据
在文档类中处理命令消息
l 使用视类
从文档类中获取数据
在视中显示数据
处理用户输入的信息
更新文档的所有视
视的滚动和缩放
l 多视与多文档
l 打印和打印预览
视结构非常适合于编写这些应用程序。
…………………………………………………………Page 427……………………………………………………………
图8。2 文档的创建
图8。3 框架窗口的创建
文档/视结构尽管有很多的优势,但是,在一些很特殊的情况下,我
们仍有可能不需要或者说不应该使用文档/视结构。
图8。4 视的创建
…………………………………………………………Page 428……………………………………………………………
最典型的一种情况是,如果我们需要移植一些过去编写的Windows应
用程序,而在这些程序中,数据的管理和显示是合在一起,要使用文
档/视结构来改写它们将会是一件消耗大量人力和物力的工作。对于
这些应用程序,最有效的方法是不使用文档/视结构。
在某些情况下,我们既不使用文档,也不使用视,而是在框架窗口中
管理和显示数据,这时,我们应该修改应用程序类的InitInstance成
员函数,创建自己的框架窗口。这种方式需要的工作量最大,并且要
对框架有相当深入的了解,然而,它提供了彻底避开文档/视结构所
带来的微小额外开销的方法。
文档对象所产生的微小额外开销来源于文档类本身以及它的基类
CCmdTarget和CObject。并且,文档还需要额外的时间来创建文档对
象、相关的视对象、框架窗口以及文档模板对象。
l 注意:
l 使用文档对象所带来的额外开销是很微小的。因此,在绝大多数
场合,我们都应该选择文档/视结构来编写基于文档的MFC应用程
序,而没有必要去考虑因为这种额外开销所带来的性能问题。
第二节 使用AppWizard创建框架应用程序
单击Microsoft Developer Studio中的菜单项File|New。。。,在
Project选项卡中选择MFC AppWizard(EXE),并在Project类和
CChildFrame类外,AppWizard所生成的类的名称是基于您所设定的工
程名称的,而类的头文件和实现文件的文件名则是基于类名的。通
常,我们只能为AppWizard所生成的视类指定另外的基类。可以使用
的基类通常包括CEditView、CFormView、CListView、
CRichEditView、CScrollView、CTreeView和CView。默认情况下,
AppWizard使用CView作为应用程序的视类的基类。事实上,其它的视
类也都是CView的派生类。使用其它的视类方便的可以实现某些而不
用我们编写额外的代码。关于这些视类的使用请参阅本章的 “
8。4
CView的派生类” 一节。
单击Finish,AppWizard将根据您在上面的步骤中所作的选择为应用
程序生成所需的框架文件。
在Introduc应用程序中,我们在所有的步骤中均使用AppWizard的默
认设置。
使用AppWizard创建单文档界面的应用程序和上面的过程几乎是完全
…………………………………………………………Page 429……………………………………………………………
一样的。主要的差别在于:AppWizard在创建单文档界面的应用程序
时,不生成CChildFrame类,并且,单文档界面应用程序的
CMainFrame类的基类为CFrameWnd,而多文档界面应用程序的
CMainFrame类的基类为CMDIFrameWnd。
由AppWizard生成的应用程序框架已经是一个可以运行的完整的应用
程序了。单击菜单项Build|Execute Introduc。exe或按快捷键
Ctrl+F5,Visual C++编译并运行由AppWizard所生成的框架应用程
序。该应用程序运行结果如图8。5所示。
图8。5 使用AppWizard创建的框架应用程序
这个应用程序框架可以运行,并且看起来好象具有完全的功能,但要
记住它仅仅是一个框架,具体的功能仍需要我们去添加。AppWizard
所生成的代码只是为我们完成了一些标准的功能。如维护文件菜单下
的最近文件列表,进行新建窗口、窗口的层叠和平铺以及重排图标
等。对于所有提供这些命令的应用程序,其实现方法几乎是完全一样
的。在过去,我们不得不编写在每一个需要实现这些功能的应用程序
时一行一行地添加相同的代码,现在,AppWizard为我们完成了这些
既枯燥乏味又容易出错的工作,从而将程序员从大量的重复性劳动中
解放出来,使他们可以有时间去从事更有意义的功能,把更多的精力
放到完成应用程序所具有的特定的功能上。
另外,我们还会发现,上面的框架应用程序还可以响应如 “打
开” 、 “保存” 等命令,工具条上的相应的按钮也可以使用。但
是,这些命令本质上什么都没有做,AppWizard只是创建了这些命令
实现的框架,程序员需要根据应用程序的特定需求去添加相应的操
作。从本章后面几节的讲述来看,添加这些操作的复杂程度比过去小
…………………………………………………………Page 430……………………………………………………………
了很多。
可以使用Workspace窗口的ClassView查看AppWizard所生成的类和类
中的成员函数,从中我们可以看到AppWizard在Introduc应用程序的
视类和文档类中所重载的基类函数。在后面的章节中,我们需要修改
这些重载函数和添加新的成员函数来为特定的应用程序实现所需的功
能。
第三节 生成文档
在文档/视结构中,文档的任务通常是对数据进行管理和维护。我们
通常将数据保存在文档类的成员变量中。视可以直接或间接的访问文
档类中的这些成员变量,并通过这种方式来显示和更新数据。关于使
用文档类的成员变量来保存数据的详细介绍请参阅 “8。3。2 把数据
保存到成员变量中” 和 “8。3。3 使用集合类管理数据”。文档还负
责将数据保存到永久存储介质中。常见的情况是将数据保存到磁盘文
件或数据库中。在Visual C++ 的与文档/视结构相关的文档中,我们
称这个过程叫串行化 (serialize)。MFC类库为数据的串行化提供了默
认的支持,我们只需要在此基础中稍加修改就可以为自定义的文档类
提供串行化支持。在 “8。3。4 数据的串行化” 一节中讲述了实现一
般的串行化过程的方法和步骤。对象的串行化需要考虑一些额外的问
题,这在 “8。3。5 串行化对象” 中讲述。文档类还可以处理命令消
息,这里所谓的命令消息是指来自如菜单、工具栏按钮和加速键的
WM_MAND通知消息。与Windows消息和控件通知消息不同,命令消
息可以被多种对象处理,这些对象除了窗口和视外,还可以是文档、
文档模板或应用程序本身。除了WM_MAND外,文档不能处理其它的
Windows消息。
8。3。1 概述
所有的文档类都以CDocument类为其基类。CDocument类提供了文档类
所需要的最基本的功能实现。更重要的是,CDocument类为文档对象
以及文档和其它对象 (如视对象、应用程序对象以及框架窗口等)交互
的实现提供了一个框架。我们所做的工作基本上是在这个已有框架的
基础上,添加与特定应用程序相关的实现。
从CDocument类派生自己的文档类所需的典型步骤为:
1。 为每一个文档类型从CDocument类 (当然也可以是其它CDocument类
的派生类)派生一个相应的文档类。
…………………………………………………………Page 431…………………………