
_START_ARTICLE_
MFC (微軟)
_START_PARAGRAPH_
微软基础类库（英语：Microsoft Foundation Classes，简称MFC）是一个微软公司提供的类库（class libraries），以C++类的形式封装了Windows API，并且包含一个（也是微软产品的唯一一个）应用程序框架，以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。
_START_SECTION_
特性
_START_PARAGRAPH_
Visual C++包含MFC应用程序向导，可用于兼容MFC的应用程序。在ATL程序中也可以手动添加MFC支持。在向导中有各种选项以定制生成的程序的功能，例如界面风格、语种、数据库开发支持、打印支持、自动化支持、ActiveX支持、网络支持、基于HTML的帮助文档支持等等。_NEWLINE_在COM开发方面，相对于ATL来说，MFC的组件比较大，代码不够短小精悍，但是支持的功能也比较多，例如有对ActiveX Document的封装类。_NEWLINE_在界面开发方面，MFC提供对消息循环的封装，使用消息映射来避免虚函数的开销。MFC也提供常用Windows通用控件的封装类。_NEWLINE_MFC扩展DLL的接口使得MFC程序可以直接调用MFC扩展DLL中的MFC类。MFC也支持在标准DLL中被使用。
_START_SECTION_
发展
_START_PARAGRAPH_
MFC是在1992年随微软的Microsoft C/C++ 7.0编译器发布的，用于面向16位Windows的软件开发。起初，MFC是作为一个应用程序框架开发的，所以定名为Application Framework eXtensions（AFX）。_NEWLINE_随着Visual Basic和Visual Studio .NET的发布，曾经一度被微软重点推荐的MFC被Visual Basic .NET、C#、Windows Forms抢走了不少市场份额，但是MFC继续在非托管软件开发中占据重要地位。在托管开发方面，MFC中也包括对Windows Forms和托管／非托管互操作的封装。微软在Windows Vista和Windows 7发布之后在MFC中增加了对新的Windows API支持。
_START_SECTION_
MFC的优点
_START_PARAGRAPH_
MFC的主要优点是可以用面向对象的方法来调用Windows API，以及能够更加便捷地开发应用程序。MFC将很多应用程序开发中常用的功能自动化，并且提供了文档框架视图结构和活动文档这样的便于自定义的应用程序框架。同时，在Visual C++内部也内建了很多对MFC的例如类向导这样的支持以减少软件开发的时间，使用类向导可以快速生成Hello World程序。
_START_SECTION_
MFC的缺点
_START_PARAGRAPH_
虽然MFC的源代码对用户是完全开放的，但是MFC的一些封装过程过于复杂，以致于新用户很难迅速掌握MFC的应用程序框架，以及在调试中定位问题的位置。同时，很多MFC对象不是线程安全的，致使在跨线程访问MFC对象时需要编写额外的代码。另外，MFC的很多类依赖于应用程序向导生成的代码，使得在使用Visual C++中其他类型的应用程序向导生成的工程中添加MFC支持的难度大大增加。
_START_SECTION_
第三方支持
_START_PARAGRAPH_
很多商用类库在MFC的基础上进一步实现了皮肤、渐变风格、多顶层窗口程序、属性列表等较受欢迎的功能；同时，在C++在线社区中，很大一部分开放的源代码也是基于MFC的。
_START_SECTION_
MFC的结构
_START_PARAGRAPH_
作为一个应用程序的开发框架，必须满足各方面的功能需求。
_START_SECTION_
CString
_START_PARAGRAPH_
CString是MFC中最常见的类之一，用于封装字符串数据结构。它只有一个数据成员m_pszData，其值为字符串的首地址，其数据类型为wchar_t*或char*。在CString的m_pszData的前面实际还分配了CSringData数据块，包含了IAtlStringMgr* pStringMgr; int nDataLength; int nAllocLength; int nRefs;等管理数据。CAtlStringMgr提供内存管理，CStringData提供共享管理。而更上层的CString提供字符串操作。CAtlStringMgr的一个成员是IAtlMemMgr接口，这是策略模式，可以引用某个内存管理类。CAtlStringMgr的另一个成员是CNilStringData。_NEWLINE_因此，每次为CString动态分配地址空间，实际分配长度为:(nChars+1)*nCharSize+sizeof(CStringData)。当执行CString的默认构造函数生成一个空串时，实际上都是构造一个CnilStringData对象。_NEWLINE_部分编译器对std::string放弃了写时复制（Copy On Write）机制。但是，CString一直采取这一机制。GetString方法返回的是只读的字符串地址；而GetBuffer方法返回的是可写的字符串地址，如果修改了字符串内容，这时需要调用ReleaseBuffer方法把新的字符串长度修改到元数据中。_NEWLINE_CString对象用作可变参数函数（如printf）的实参时，由于无法通过形参类型确定调用哪个CString的类型转换操作符函数，因此有必要显式指明要转换的类型。如果需要在函数的参数传递CString，由于CString使用了引用计数，因此函数参数传递一个CString对象是可行的；需要修改其内容时，推荐使用const CString&。