1.06k likes | 1.17k Views
第二章 揭开 MFC 应用程序框架的秘密. 前一章我们已经学会了使用 Visual C++ 6.0 和 Visual C++ .NET 的 向导生成 Windows API 应用程序 的方法,并对 Windows 应用程序 的基本结构特点和运行机制有所了解。仔细分析这类程序,不 难发现,这类程序功能的实现是建立在对 API 函数的调用之上 的,而 API 函数是通过参数形式对 GUI 元素(如窗口、对话框、 菜单、设备场境等 Windows 类实例 )进行相应操作的。从程序
E N D
前一章我们已经学会了使用 Visual C++ 6.0 和Visual C++ .NET 的 向导生成Windows API 应用程序的方法,并对 Windows 应用程序 的基本结构特点和运行机制有所了解。仔细分析这类程序,不 难发现,这类程序功能的实现是建立在对 API 函数的调用之上 的,而 API 函数是通过参数形式对 GUI元素(如窗口、对话框、 菜单、设备场境等 Windows 类实例)进行相应操作的。从程序 的组成上看,这些 Windows 类实际上只是用于描述 GUI元素的 形状、尺寸、风格等属性的数据结构对象,而不是将属性和建 立在属性之上的操作封装在一起的 C++类对象。所有 Windows 类的实例是由 Windows 系统统一管理,并通过系统的编程接口 (API 函数)提供对这些类实例的所有操作。
因此,实现对 GUI元素的操作都必须首先通过 API 函数直接 或间接地在系统中注册并创建(分配内存空间并建立了索引) 所对应的 Windows 类的实例,并获得访问实例的句柄;然后以 句柄为参数调用特定 API 函数,以便对指定的 GUI 元素实现所 需要的操作。这种操作与被操作的数据的分离是面向过程设计 的基本特点,而是面向对象程序设计所不允许的。因此,虽然 也可以按照面向对象的设计方法在API 应用程序中加入 C++类 的定义和使用,但不能从根本上改变程序的面向过程设计。
MFC (Microsoft Foundation Class Library) 是 Microsoft公司提供的 建立在 Windows 类和 Win32 API基础上的 C++类库。库中的 C++ 类几乎涵盖了 Windows 程序所需要的主要 Windows 类和相应的 API 函数功能。Visual C++集成环境中的 MFC AppWizard能使用 MFC中的框架类为编程者提供一个标准的面向对象的Windows 应用程序框架。借助这个框架,编程者可以方便地使用 MFC 提 供的 C++类比较轻松地开发各类面向对象设计的 Windows 应用 程序。从面向对象程序设计的角度出发,对 Visual C++ 从入门到 精通的过程,主要是学习和熟悉 MFC及其 MFC 应用程序框架的 过程,它将贯穿在本课程的整个学习过程中。
2.1 用 AppWizard开发基于 MFC的窗口程序 通过一个 MFC窗口程序的生成过程,学习和了解: ·如何使用 AppWizard创建一个 MFC窗口程序项目。 ·自动生成的 MFC窗口程序框架的功能。 ·自动生成的 MFC 窗口程序框架由那些类组成。 ·自动生成的 MFC窗口程序框架包括那些文件。 ·如何向框架中添加代码。
2.1.1 生成 MFC窗口程序 1 使用 Visual C++ 6.0集成开发环境 ⑴ 在菜单 “File” 中选择菜单项 “New” 打开创建新项目的向导。
⑵在该向导中选择应用程序项目的框架模板 在 Project中选择 MFC AppWizard(exe)创建命名为 “Hello”的 MFC 窗口程序项目。
⑶使用 MFC AppWizard(exe) 设置应用程序项目的选项 ① MFC AppWizard(exe) - step 1 属性页: 选择程序类型和资源语言。
② MFC AppWizard(exe) - step 2 of 6 属性页: 设置数据库。缺省选项 None,表示不支持数据库操作。
③ MFC AppWizard(exe) - step 3 of 6 属性页: 设置 OLE支持选项。缺省选项 None,表示无 OLE 支持。
④ MFC AppWizard(exe) - step 4 of 6 属性页: 设置应用程序外观。此例使用缺省选项,即: Docking toolbar支持靠边的工具栏 Initial Status bar支持初始化状态栏 Printing and print preview支持打印和打印预览 3D controls支持 3D控件 Normal支持普通风格的工具栏,支持显示4 个最近使用过的文件名。
⑤ MFC AppWizard(exe) - step 5 of 6 属性页: 设置项目风格和 MFC 的使用方式。缺省选项,表示: MFC Standard提供一个标准的 MFC应用程序 Yes please提供框架的程序注释 As a shared DLLMFC被链接为共享动态链接库
⑥ MFC AppWizard(exe) - step 6 of 6 属性页: 允许修改向导缺省创建的类名、基类、头文件名和实现 文件名。
⑦New Project Information 属性页: 显示所生成的应用程序的组成信息。
⑷应用程序项目的编译运行 一个具有标准窗口界面的单文档程序框架能成功运行。 ⑸查看项目中自动生成的信息 打开所生成的项目目录会发现 MFC AppWizard 自动创建了 许多文件,这些文件包括: ①项目信息文件 ·工作区文件(.dsw):保存当前工作区所包含项目的信息。 ·项目文件(.dsp):包含了当前项目的设置、项目中包含的 文件等信息。 ·make文件(.mak):用于在集成环境外生成可执行文件。 注意:make文件只有在“Project” 菜单中执行 Export Makefile… 命令时,才产生。
·类信息文件(.clw):该文件含有使用类向导(Class Wizard) 操作(编辑现有类、增加新类,创建和编辑消息映射,对 话框所需的数据,创建虚拟成员函数等) 时需要使用的类 信息。如果类向导文件 .clw被删除,则在使用 Class Wizard时会出现如下信息:
此时如果按 “Yes” 按钮,则选择重建 .clw 文件,即显示如下 操作对话框: 按 OK 按钮,就可以完成类信息文件的重建。
② 应用程序源文件和头文件 ·头文件(.h):包含应用程序类头文件、主窗口类头文件、 文档类头文件和视图类头文件,它们分别用于定义从 MFC 相应的基类派生出的应用程序框架类。 ·源文件(.cpp):包含有应用程序类源文件、主窗口类源文 件、文档类源文件和视图类源文件,它们分别为相应头文 件中类定义提供实现文件。 ③资源文件 ·资源描述文件(.rc):保存所有被创建的资源描述信息。 ·资源头文件(resource.h):主要用于定义资源描述文件中 的标识的定义。
·资源文件目录 res 中包含了资源描述文件(.rc)中需要导入 的图标、光标、位图资源信息文件等。 ④预编译头文件 StdAfx.h和 StdAfx.cpp这两个文件用于建立一个预编译头文 件(.pch) 和一个预定义的类型文件 StdAfx.obj。程序中常用 的 MFC 的头文件都放在 StdAfx.h 中,如 afxwin.h、afxext.h、 afxdisp.h、afxcmn.h等。Stdafx.h被包含在 stdAfx.cpp 中。由于编 译器能够识别哪些头文件已被预编译过,如果不改变 StdAfx.h 中所包含的头文件,则 StdAfx.cpp只需被编译一次。如果在 StdAfx.h中添加新头文件后,则必须重新编译 StdAfx.cpp,使 添加的头文件加入预编译头文件(.pch) 。
⑤其他文件 ⑥ 生成的 C++ 类 ·CHelloApp:应用程序类,基类为 CWinApp,负责程序的初 始化和结束处理; ·CMainFrame:主窗口类,基类为 CFrameWnd,负责主窗口 和操作界面(菜单、工具栏、状态栏等)的创建、显示; ·CHelloDoc:文档类,基类为 CDocument,负责应用程序的 数据存储、修改和管理; ·CHelloView:视图类,基类为 CView,负责为数据提供显示 窗口。
2 使用 Visual C++ NET 集成开发环境 ⑴在子菜单 “File” 中选择菜单项 “New” 的子项 “Project…” 打开创 建新程序项目的 “New Project” 属性表。
⑵在工程项目“New Project” 属性表中选择 Visual C++ - MFC – MFC AppWizard创建一个命名为 Hello 的MFC窗口程序 。
⑶在项目向导“MFC Application Wizard” 属性表中可以进行项目的 各个属性设置。该表的左边列出了各个分类属性页的选择, 右边显示当前所选分类属性的信息,并提供修改属性的交互 界面,右下部提供了该属性表的向导按钮。因此,该属性表 既可以按照一般属性表使用,也可以按照向导使用。
① “Overview” 属性页: 在该页中显示了工程项目的当前主要属性,例如本例中的 主要缺省属性为: ·Mutiple document interface MDI 多文档界面 ·No database support无数据库支持 ·No compount document support 无复合文档支持 如果无须修改工程项目的当前属性和添加其他属性,则按 “Finish” 按钮完成工程项目创建,否则按 “Next” 按钮,转换 到后一属性页,或通过右边的属性页分类选择,转换到任 意一个需要修改属性的页。本例只修改 Application Type。
② “Application Type” 属性页: 在该页中可以确定工程项目类型的属性,这些属性分为三 部分: ·Application type:确定应用程序的界面类型。与 VC 6.0 的 AppWizard Step1 属性页比较,该属性页增加了 Mutiple top-level document 界面类型和 Use Unicode libraries 选 择。本例中只须将缺省界面类型 Mutiple documents 修改为 Single document。 ·Project style:确定项目的风格为 Windows Explorer 或 MFC Standard,本例为缺省风格:MFC Standard 。VC 6.0 中, 该属性在AppWizard Step 5 of 6 属性页中。
·Use of MFC:确定项目的 MFC 使用方式。在 VC 6.0 中, 该属性的设置也在 AppWizard Step 5 of 6 属性页中。
如果需要修改或添加其他属性,则可按“Next”或“Previous”如果需要修改或添加其他属性,则可按“Next”或“Previous” 按钮,转换到前一或后一属性页,或通过右边的属性页分 类选择,转换到任意一个需要修改属性的页;否则可以直 接按“Finish”按钮完成工程项目的创建。 ③ “Compound Document Support” 属性页: 该页中可以确定工程项目的复合文档属性,在 Visual C++ 6.0 中,这些属性的设置在AppWizard Step 3 of 6 属性页中。 本例为缺省属性“None”无复合文档支持。
如果需要修改或添加其他属性,则可按“Next”或“Previous”如果需要修改或添加其他属性,则可按“Next”或“Previous” 按钮,转换到前一或后一属性页,或通过右边的属性页分 类选择,转换到任意一个需要修改属性的页;否则可以直 接按 “Finish” 按钮完成工程项目的创建。
在该属性页中可以修改项目的文档描述串(文件扩展名、在该属性页中可以修改项目的文档描述串(文件扩展名、 主框架窗口标题、文档类型名等)。在 Visual C++ 6.0 中, 设置这些属性在AppWizard Step 4 of 6 的 “Advanced…” 附加 属性页中完成的。本例使用缺省的文档描述串。 如果需要修改或添加其他属性,则可按“Next” 或“Previous” 按钮,转换到前一或后一属性页,或通过右边的属性页 分类选择,转换到任意一个需要修改属性的页;否则可以 直接按“Finish”按钮完成工程项目的创建。
⑤ “Database Supprot” 属性页: 在该页中可以确定项目的数据库属性,在 VC 6.0 中,该属 性的设置在AppWizard Step 2 of 6 属性页中。
如果需要修改或添加其他属性,则可按 “Next” 或 “Previous” 按钮,转换到前一或后一属性页,或通过右边的属性页分 类选择,转换到任意一个需要修改属性的页;否则可以直 接按 “Finish” 按钮完成工程项目的创建。 ⑥ “User Interface Features” 属性页: 在该页中可以确定工程项目的用户界面特征属性,在 VC 6.0中,这些属性的设置在AppWizard Step 4 of 6 属性页 中完成。本例为缺省的用户界面特征属性。
如果需要修改或添加其他属性,则可按“Next”或“Previous”如果需要修改或添加其他属性,则可按“Next”或“Previous” 按钮,转换到前一或后一属性页,或通过右边的属性页 分类选择,转换到任意一个需要修改属性的页;否则可以 直接按“Finish”按钮完成工程项目的创建。
在该页中可以确定工程项目的高级属性如下: ·Context-sensitive Help 上下文相关的帮助文件集合 ·Printing and print preview 打印和打印预览 ·MAPI (Messaging API) 允许调用通讯功能MAPI ·Windows Socket 允许使用Windows Socket ·Number of files on recent file list 显示最近用过文件的数目 (在VC 6.0 中,上述属性在 AppWizard 4 of 6属性页中) ·Automation允许成为其他程序或脚本的操作对 象(在VC 6.0 中,该属性在 AppWizard 3 of 6属性页中) ·Active Accessibility
·Common Control Manifest (上述两项属性是 Visual C++ .NET中新增的) VC 6.0中,这些属性的设置在AppWizard Step 4 of 6 属性页 中完成。本例为缺省的用户界面特征属性。 如果需要修改或添加其他属性,则可按 “Next” 或 “Previous” 按钮,转换到前一或后一属性页,或通过右边的属性页 分类选择,转换到任意一个需要修改属性的页;否则可以 直接按 “Finish” 按钮完成工程项目的创建。
在该页中显示了工程项目自动生成的构成程序基本框架的在该页中显示了工程项目自动生成的构成程序基本框架的 类的缺省命名、派生的基类以及这些类的定义文件和实现 文件的命名属性。这些属性中一部分是允许修改的,而另 一部分是不允许修改的。本例使用缺省命名属性,不做任 何修改。在 Visual C++ 6.0 中,这些命名属性的显示和修改 是在 AppWizard Step 6 of 6属性页中完成。 ⑷应用程序项目的编译运行 一个具有标准窗口界面的单文档应用程序成功运行,但视 窗中并不显示任何内容。
⑸查看项目中自动生成的信息 工程项目的所有信息文件被分别保存在三个不同层次的目 录中: ① 项目主目录 该目录与项目名同名,本例的项目主目录名为 Hello 。 在该目录中包含了一个与项目主目录同名的子目录(用 于存放项目的所有源文件)和三个项目管理信息文件: ·项目/解决方案文件(.sln) 文件名与项目同名,用于打开和管理已建项目/解决方 案,该文件不可以删除。
·Intellisense database 文件(.ncb) 文件名与项目同名,用于保存已建项目/解决方案的辅助 信息,该文件可以删除。 ·用户选项信息文件(.suo) 文件名与项目同名,用于保存已建项目/解决方案的辅助 信息,该文件可以删除。 ② 源代码子目录中包含了项目中所有的源代码文件(.h, .cpp, .rc),命名为 res 的资源子目录和三个信息文件: ·项目文件(.vcproj) 文件名与项目同名,用于打开和管理已建项目/解决方 案,该文件不可以删除。
·用户选项信息文件(.vcproj.…) 文件名与项目同名,用于保存已建项目/解决方案的辅助 信息,该文件可以删除。 ·readme文件(.txt) 文件名与项目同名,用于阅读已建项目/解决方案的说明 信息,该文件可以删除,但建议不要删除。 ③ 资源子目录 res 该目录中包含了资源描述文件(.rc)中需要导入的图标、 光标、位图资源信息文件等。 ④预编译头文件 与 Visual C++ 6.0 中相同。 ⑤ 生成的 C++ 类 与 Visual C++ 6.0 中相同。
⑥ 项目在 Debug 方式下编译链接后,会在项目主目录中和项 目源代码目录中分别创建一个以“Debug” 命名的子目录。可 执行文件在主目录的 “Debug” 子目录中;源代码目录中的 “Debug” 子目录中包含了编译链接过程中所产生的中间文 件。这两个子目录均可删除。 ⑦ 项目在 Release 方式下编译链接后,会在项目主目录中和 项目源代码目录中分别创建一个以 “Release” 命名的子目 录。可执行文件在主目录的 “Release” 子目录中;源代码目 录中的 “Release” 子目录中包含了编译链接过程中所产生的 中间文件。这两个子目录均可删除。
2.1.2使用项目工作区窗口浏览和添加代码 MFC AppWizard为我们提供一个面向对象的Windows 应用程序 框架,它为程序的构造和运行建立了最基本的、优化的框架, 使软件工作者避免了设计开发任何程序都需要的程序框架建造 工作(该工作很烦琐,但具有一致性),而可以集中精力解决 所设计程序需要完成的特定功能的设计上,并为实现设计在程 序框架中添加新类、资源以及相应的消息消息映射和消息处理 函数等等。这将大大有利于程序设计方案简化和优化。 为了便于向程序框架中添加正确的代码,VC 还提供了项目工 作区和 Class Wizard这样的可视化管理工具,编程者可以借助这 些工具,方便地完成对项目中几乎所有代码的添加、浏览查看 和修改。
1使用项目工作区的ClassView ·浏览和修改项目中已有类的定义和类成员函数的定义; ·为项目添加新类,并为类添加类数据成员和类成员函数; ·其他。 在本例中,为了实现在视窗中显示文本 “Hello World!”需要在 类 CHelloView的成员函数 OnDraw中增加如下代码: void CHelloView::OnDraw(CDC* pDC) { CHelloDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->TextOut(10, 10, "Hello World!"); }
2使用项目工作区的 ResourceView ·浏览查看项目中的所有资源; ·修改项目中的已有资源; ·为项目添加新资源。 3使用项目工作区的 FileView ·浏览查看项目中与生成可执行程序有关的所有文件; ·在被打开的文件中修改和添加代码; ·为项目增加或删除文件。 在 Visual C++.NET 中相应的视图称为 Solution Explorer。