`
huozheleisi
  • 浏览: 1234290 次
文章分类
社区版块
存档分类
最新评论

MFC类库的产生与发展

 
阅读更多

MFC类库的产生与发展

在Microsoft推出Windows 3.0之后,Windows操作系统受到越来越多的人的青睐。但是不久,开发人员发现撰写Windows应用程序是重复、厌烦的过程,而且效率极低。因为每一个窗口都需要在窗口函数中处理大量的消息,导致出现大量的重复代码。

随着C++语言的盛行,开发人员发现利用C++语言的特性来封装Windows API和Windows应用程序的开发可以明显地提高程序的开发效率。于是,人们对这种新的开发模式有了强烈的需求。在这种情况下,Microsoft公司和其他一些大的厂商开始从事Windows框架的设计。MFC就在这种背景下诞生了。

MFC的英文全称是Microsoft Fundation Class Library,即微软基础类库。从其产生至今已经发展了十几个版本,表1.4列出的是MFC的发展过程。

表1.4 MFC发展过程

MFC

Visual C++

MFC 1.0版本

Microsoft C/C++ 7.0版本

MFC 2.0版本

Visual C++ 1.0版本

MFC 2.5版本

Visual C++ 1.5版本

MFC 3.0版本

Visual C++ 2.0版本

MFC 3.1版本

Visual C++ 2.1版本

MFC 3.2版本

Visual C++ 2.2版本

MFC 4.0版本

Visual C++ 4.0版本

MFC 4.1版本

Visual C++ 4.1版本

MFC 4.2版本

Visual C++ 4.2版本

MFC 4.21版本

Visual C++ 5.0版本

MFC 6.0版本

Visual C++ 6.0版本

MFC 7.0版本

Visual C++.NET 2002版本

MFC 7.1版本

Visual C++.NET 2003版本

MFC 8.0版本

Visual C++.NET 2005版本

1.5.2 MFC类库层次

MFC中的类按照功能的不同,可以分为不同的层次。图1.10显示了MFC中的所有类及类库层次。

1.5.3 MFC常用数据类型

MFC中的数据类型与Windows SDK开发包中的数据类型多数是一致的,但也有一些数据类型是MFC独有的。表1.5列出了MFC中使用的数据类型。

表1.5中列出的最后两个数据类型是MFC所特有的。

1.5.4 MFC全局函数

在MFC类库中,除了提供实现各种功能的类以外,还提供许多全局函数。具体介绍如下。

文本框: 图1.10  MFC中的类及类库层次

表1.5 MFC数据类型

数 据 类 型

描 述

BOOL

布尔值,取值为TRUE或FALSE

BSTR

32位字符指针

BYTE

8位无符号整数

COLORREF

用作颜色值的32位数值

DWORD

32位无符号整数,或者段的地址和与之相关的偏移量

LONG

32位有符号整数

LPARAM

32位值,作为窗口函数或回调函数的参数

LPCSTR

指向字符串常量的32位指针

LPSTR

32位字符串指针

LPCTSTR

指向兼容Unicode和DBCS字符集的字符串常量32位指针

LPTSTR

指向兼容Unicode和DBCS字符集的字符串32位指针

LPVOID

指向一个未定义类型的32位指针

LRESULT

窗口函数或回调函数返回的32位值

UINT

32位无符号整数

WNDPROC

指向一个窗口函数的32位指针

WORD

16位无符号整数

WPARAM

作为参数传递给窗口函数或回调函数的值

POSITION

用于标记集合中一个元素的位置

LPCRECT

指向一个RECT结构体常量的32位指针

1.MFC诊断函数

为了调试的方便,MFC提供了多个诊断函数,如表1.6所示。

表1.6 MFC诊断函数

函 数 名 称

描 述

AfxCheckMemory

检查当前分配的所有内存的完整性

AfxDump

如果在调试器内调用,则转存对象的状态

AfxDumpStack

生成当前栈的一个映像,该函数通常被静态链接

AfxEnableMemoryTracking

打开或关闭内存跟踪

AfxIsMemoryBlock

检验一个内存块是否被正确地分配

AfxIsValidString

检验一个字符串指针是否有效

AfxSetAllocHook

允许在每次进行内存分配时调用一个函数

AfxDoForAllClasses

对所有从CObject继承的支持运行时检查的类执行一个特定的功能

AfxDoForAllObjects

对所有从CObject继承的用new分配内存的对象执行一个指定的功能

2.异常抛出函数

为了使程序具有健壮性,MFC提供了多个异常抛出函数,如表1.7所示。

表1.7 异常抛出函数

函 数 名 称

描 述

AfxThrowArchiveException

抛出一个档案异常

AfxThrowFileException

抛出一个文件异常

续表

函 数 名 称

描 述

AfxThrowMemoryException

抛出一个内存异常

AfxThrowNotSupportedException

抛出一个不支持的异常

AfxThrowResourceException

抛出一个Windows未找到资源的异常

AfxThrowUserException

在用户初始化的程序动作中抛出一个异常

AfxThrowOleException

抛出一个OLE异常

AfxThrowOleDispatchException

在OLE自动化函数内抛出异常

AfxThrowDaoException

从代码中抛出一个CDaoException异常

AfxThrowDBException

从代码中抛出一个CDBException异常

3.字符串格式和消息框函数

MFC除了提供CString类操作字符串外,还提供了两个全局函数,如表1.8所示。

表1.8 字符串格式和消息框函数

函 数 名 称

描 述

AfxFormatString1

用一个字符串替换给定字符串中的格式字符“%1”

AfxFormatString2

用两个字符串替换给定字符串中两个格式字符“%1”和“%2”

AfxMessageBox

显示一个消息框

4.应用程序信息和管理函数

MFC提供的与应用程序有关的全局函数如表1.9所示。其中,有许多函数在开发应用程序过程中经常使用。

表1.9 应用程序信息和管理函数

函 数 名 称

描 述

AfxFreeLibrary

减少已调入内存的动态链接库模块的引用计数;当引用计数减到0时,该模块就会被释放

AfxGetApp

返回应用程序对象CWinApp的一个指针

AfxGetAppName

返回应用程序的名称

AfxGetInstanceHandle

返回应用程序实例句柄

AfxGetMainWnd

返回指向非OLE应用程序的当前主窗口指针,或者是服务器程序的线程框架窗口

AfxGetResourceHandle

返回应用程序默认的资源

AfxInitRichEdit

为应用程序初始化RichEdit控件

AfxLoadLibrary

调入一个DLL模块,同时返回一个句柄,通过该句柄可以获得DLL中函数的地址

AfxRegisterWndClass

注册一个Windows窗口类,用它来代替MFC自动注册的窗口类

AfxSocketInit

在应用程序的InitInstance方法中调用,用于初始化套接字

AfxSetResourceHandle

设置应用程序默认的资源句柄

AfxRegisterClass

在使用MFC的DLL中注册窗口类

AfxBeginThread

创建一个新的线程

AfxEndThread

结束一个线程

AfxGetThread

获取指向当前CWinThread对象的指针

AfxWinInit

由MFC提供的WinMain函数直接调用,在GUI应用程序中,用于初始化MFC

5.集合类帮助函数

集合类帮助函数多用于数组操作。表1.10列出了MFC提供的集合类帮助函数。

表1.10 集合类帮助函数

函 数 名 称

描 述

CompareElements

比较元素是否相同

ConstructElements

当生成一个元素时必须实现的动作

CopyElements

将元素从一个数组中复制到另一个数组中

DestructElements

当销毁一个数组时需要实现的动作

DumpElements

提供了面向流的诊断输出

HashKey

计算一个Hash键

SerializeElements

将元素保存到文件中,或从文件中获得元素

6.记录字段交换函数

记录字段交换函数用于记录集数据与变量的交互。表1.11列出了与记录字段相关的函数。

表1.11 记录字段交换函数

函 数 名 称

描 述

RFX_Binary

传送CByteArray类型的字节数

RFX_Bool

传送布尔数据

RFX_Byte

传送单个字节数据

RFX_Date

传送CTime或TIMESTAMP_STRUCT类型的时间和日期数据

RFX_Double

传送双精度浮点数据

RFX_Int

传送整型数据

RFX_Long

传送长整型数据

RFX_LongBinary

通过CLongBinary类的对象传送二进制大对象

RFX_Single

传送浮点数据

RFX_Text

传送字符串数据

RFX_Binary_Bulk

传送二进制数据的数组

RFX_Bool_Bulk

传送布尔数据的数组

RFX_Date_Bulk

传送TIMESTAMP_STRUCT数据的数组

RFX_Double_Bulk

传送双精度浮点数据数组

RFX_Int_Bulk

传送整型数据数组

RFX_Long_Bulk

传送长整型数据数组

RFX_Single_Bulk

传送浮点数据数组

RFX_Text_Bulk

传送LPSTR数据数组

7.OLE相关函数

为了支持OLE技术,MFC对OLE进行了封装,同时提供了一些全局函数用于OLE操作,如表1.12所示。

表1.12 OLE相关函数

函 数 名 称

描 述

AfxOleInit

初始化OLE库

AfxOleCanExitApp

判断应用程序是否能够结束

AfxOleGetMessageFilter

获取应用程序当前的消息过滤器

AfxOleGetUserCtrl

获取当前的用户控制标记

续表

函 数 名 称

描 述

AfxOleSetUserCtrl

设置或清除用户控制标记

AfxOleLockApp

增加应用程序中活动对象的全局计数

AfxOleUnlockApp

减少应用程序中活动对象的全局计数

AfxOleRegisterServerClass

在OLE系统注册表中注册一个服务器

AfxOleSetEditMenu

实现TypeName Object命令的用户接口

AfxOleRegisterControlClass

在注册数据库中添加控件类

AfxOleRegisterPropertyPageClass

在注册数据库中添加控件的属性页类

AfxOleRegisterTypeLib

在注册数据库中添加控件的类型库

AfxOleUnregisterClass

从注册数据库中删除控件类或属性页类

AfxOleUnregisterTypeLib

从注册数据库中删除控件的类型库

8.Internet URL解析全局函数

为了获得URL字符串的相关信息,MFC提供了两个全局函数,如表1.13所示。

表1.13 Internet URL解析全局函数

函 数 名 称

描 述

AfxParseURL

分析一个URL字符串,返回服务器的类型及内容

AfxParseURLEx

分析一个URL字符串,返回服务器的类型及内容,同时返回系统用户的名字和密码

1.5.5 开发基于MFC的应用程序

在1.4.5节中介绍了利用Windows API开发Win32应用程序。本节将介绍如何开发基于MFC的应用程序。

*实例位置:光盘/mingrisoft/sl/01/02/MFCApp.dsw

具体步骤如下。

(1)单击“File/New”菜单项,打开“New”对话框,选择“Projects”选项卡,如图1.11所示。

图1.11 MFC应用程序

(2)在列表中选择“MFC AppWizard(exe)”选项,在“Project name”编辑框中输入工程名称,此时“OK”按钮变为可用,单击该按钮进入“MFC AppWizard-Step1”对话框,如图1.12所示。

图1.12 “MFC AppWizard-Step1”对话框

(3)在“MFC AppWizard-Step1”对话框中选择应用程序的类型。这里共有3种类型可供选择,分别为“Single document(单文档应用程序)”、“Multiple documents(多文档应用程序)”和“Dialog based(对话框应用程序)”。这里选择“Dialog based”,即创建基于对话框的应用程序。

(4)单击“Next”按钮,进入“MFC AppWizard-Step 2 of 4”对话框,如图1.13所示。

图1.13 “MFC AppWizard-Step 2 of 4”对话框

(5)保留默认的设置,单击“Next”按钮,进入“MFC AppWizard-Step 3 of 4”对话框,如图1.14所示。

(6)单击“Next”按钮,进入“MFC AppWizard-Step 4 of 4”对话框,在该对话框中列出了MFC向导创建的类,如图1.15所示。

图1.14 “MFC AppWizard-Step 3 of 4”对话框

图1.15 “MFC AppWizard-Step 4 of 4”对话框

(7)单击“Finish”按钮,完成工程的创建。运行程序,效果如图1.16所示。

图1.16 MFC应用程序

使用MFC应用程序向导,没有编写一句代码,就创建出了一个对话框。与1.4.5节中的程序开发过程相比,简单了许多,这就是MFC的优势。

但是,读者似乎会产生疑问,在上面的工程中并没有发现程序的入点函数WinMain。下面将剖析程序的执行过程,读者在其中会找到答案。

在编译应用程序的时候,首先会构造工程中的全局对象,即先创建全局对象。在上面创建的工程中,读者可以找到MFC应用程序向导创建的全局对象theApp。因此会执行theApp类的构造函数,接着链接器加载代码,执行_tWinMain函数。用户可以按<F11>键进入到_tWinMain函数,如图1.17所示。

图1.17 _tWinMain函数

_tWinMain函数与WinMain函数有什么关系呢?将光标定位在“_tWinMain”处,按<F12>键查看其定义,发现_tWinMain其实是一个宏,等价于WinMain函数,如图1.18所示。

图1.18 _tWinMain宏定义

在_tWinMain函数中,调用了AfxWinMain函数,而AfxWinMain函数又调用了AfxWinInit函数,然后又调用了应用程序的InitApplication方法、InitInstance方法,如图1.19所示。

图1.19 AfxWinMain函数

在图1.19中注意“pThread->InitInstance()”语句,其中pThread是一个CWinThread对象指针,通过调用AfxGetThread函数获得。上文中笔者说在AfxWinMain函数中调用了应用程序的InitInstance方法,应用程序与pThread有何关系呢?其实应用程序CWinApp的父类就是CWinThread。在CWinThread类中定义了虚拟方法InitInstance,依据动态绑定的原则,“pThread->InitInstance()”语句实际上调用的是应用程序的InitInstance方法。本例中InitInstance方法代码是由MFC应用程序向导自动生成的,代码如下:

BOOL CMFCAppApp::InitInstance()

{

AfxEnableControlContainer();

#ifdef _AFXDLL

Enable3dControls();

#else

Enable3dControlsStatic();

#endif

CMFCAppDlg dlg; //定义一个对话框对象

m_pMainWnd = &dlg; //将对话框设置为应用程序的主窗口

int nResponse = dlg.DoModal(); //创建一个模态对话框

if (nResponse == IDOK)

{

}

else if (nResponse == IDCANCEL)

{

}

return FALSE;

}

在应用程序的InitInstance方法中,对话框dlg调用了DoModal方法,该方法用于创建一个模态对话框。DoModal方法在内部调用一系列的函数,实现窗口类的注册、创建窗口、进入消息循环等功能。有关模态对话框的相关知识在后面章节会详细介绍。

分享到:
评论

相关推荐

    MFC实战参考程序

    1.5.1 MFC类库的产生与发展 15 1.5.2 MFC类库层次 15 1.5.3 MFC常用数据类型 15 1.5.4 MFC全局函数 15 1.5.5 开发基于MFC的应用程序 20 1.6 Visual C++ 6.0集成开发环境 24 1.6.1 开发环境 24 1.6.2 ...

    MFC Windows程序设计(第2版修订版)--源代码

    一部分是由于VisualC++代码生成向导所生成的代码所致,另一个原因是因为无数行代码隐藏在MFC类库中。这正是本书使用特殊的方法来写MFC的缘由。本书从让您亲自手写代码开始(不用向导),使用MFCl.0的应用程序结构风格...

    MFC Windows程序设计(第2版修订版)--详细书签版2卷

    一部分是由于VisualC++代码生成向导所生成的代码所致,另一个原因是因为无数行代码隐藏在MFC类库中。这正是本书使用特殊的方法来写MFC的缘由。本书从让您亲自手写代码开始(不用向导),使用MFCl.0的应用程序结构风格...

    MFC Windows程序设计(第2版修订版)--详细书签版1卷

    一部分是由于VisualC++代码生成向导所生成的代码所致,另一个原因是因为无数行代码隐藏在MFC类库中。这正是本书使用特殊的方法来写MFC的缘由。本书从让您亲自手写代码开始(不用向导),使用MFCl.0的应用程序结构风格...

    C#微软培训资料

    2.2 公用语言运行时环境与公用语言规范.13 2.3 开 发 工 具 .17 2.4 小 结 .19 第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 ...

    C++标准库介绍.pdf

     跨平台GUI库其类层次极像MFC所以有文章介绍从MFC到WxWindows代码移植以实现跨平台功能通过多 年开发也是个日趋完善GUI库支持同样不弱于前面两个库并且是完全开放源代码新近C Builder XGUI设计器就 是基于这个库 4...

Global site tag (gtag.js) - Google Analytics