MFC (微軟)

MFC (微軟)

此条目的主題是微软基础类库。关于与「MFC (微軟)」標題相近或相同的条目,請見「MFC」。

微软基础类库(英語:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API,并且包含一个(也是微软产品的唯一一个)应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。

特性[编辑]

Visual C++包含MFC应用程序向导,可用于兼容MFC的应用程序[1]。在ATL程序中也可以手动添加MFC支持[2]。在向导中有各种选项以定制生成的程序的功能,例如界面风格、语种、数据库开发支持、打印支持、自动化支持、ActiveX支持、网络支持、基于HTML的帮助文档支持等等。

在COM开发方面,相对于ATL来说,MFC的组件比较大,代码不够短小精悍,但是支持的功能也比较多,例如有对ActiveX Document的封装类[3]。

在界面开发方面,MFC提供对消息循环的封装,使用消息映射来避免虚函数的开销。MFC也提供常用Windows通用控件的封装类。

MFC扩展DLL的接口使得MFC程序可以直接调用MFC扩展DLL中的MFC类。MFC也支持在标准DLL中被使用。

发展[编辑]

MFC是在1992年随微软的Microsoft C/C++ 7.0编译器发布的,用于面向16位元Windows的软件开发。起初,MFC是作为一个应用程序框架开发的,所以定名为Application Framework eXtensions(AFX)。[4]

随着.NET框架的发布,曾经一度被微软重点推荐的MFC被Visual Basic .NET、C#、Windows Forms抢走了不少市场份额,但是MFC继续在非托管软件开发中占据重要地位。在托管开发方面,MFC中也包括对Windows Forms和托管/非托管互操作的封装。微软在Windows Vista和Windows 7发布之后在MFC中增加了对新的Windows API支持[5][6]。

MFC的优点[编辑]

MFC的主要优点是可以用面向对象的方法来调用Windows API,以及能够更加便捷地开发应用程序。MFC将很多应用程序开发中常用的功能自动化,并且提供了文档框架视图结构和活动文档这样的便于自定义的应用程序框架。同时,在Visual C++内部也内建了很多对MFC的例如类向导这样的支持以减少软件开发的时间,使用类向导可以快速生成Hello World程序。

MFC的缺点[编辑]

虽然MFC的源代码对用户是完全开放的,但是MFC的一些封装过程过于复杂,以致于新用户很难迅速掌握MFC的应用程序框架,以及在调试中定位问题的位置。同时,很多MFC对象不是线程安全的,致使在跨线程访问MFC对象时需要编写额外的代码。另外,MFC的很多类依赖于应用程序向导生成的代码,使得在使用Visual C++中其他类型的应用程序向导生成的工程中添加MFC支持的难度大大增加。

第三方支持[编辑]

很多商用类库在MFC的基础上进一步实现了皮肤、渐变风格、多顶层窗口程序、属性列表等较受欢迎的功能;同时,在C++在线社区中,很大一部分开放的源代码也是基于MFC的。

版本[编辑]

產品

程式庫

版本

發佈日期

名稱

版本

Microsoft C/C++ 7.0

mafxcw.lib

MFC 1.0

1992

Microsoft Visual C++ 1.0

Visual C++ 1.0

mfc200.dll

MFC 2.0

Visual C++ 1.5

mfc250.dll

MFC 2.5

Visual C++ 1.51

mfc250.dll

MFC 2.51

Visual C++ 1.52c

mfc250.dll

MFC 2.5 ( Windows 3.x 的最後發展平台 )

Microsoft Visual C++ 2.0

Visual C++ 2.0

mfc30.dll

MFC 3.0

Visual C++ 2.1

mfc30.dll

MFC 3.1

Visual C++ 2.2

mfc30.dll

MFC 3.2

Microsoft Visual C++ 4.0

Visual C++ 4.0

mfc40.dll

MFC 4.0 (mfc40.dll 包含於 Windows 95)

1995年8月

Visual C++ 4.1

mfc40.dll

MFC 4.1

Visual C++ 4.2

mfc42.dll

MFC 4.2 (mfc42.dll 包含於 Windows 98 初版)

1998年3月

內含於 Visual C++ 3.0

mfc42.dll

MFC 4.2

Microsoft Visual C++ 5.0

Visual C++ 5.0

mfc42.dll

MFC 4.21, 是 MFC 4.2 的主要更新

Microsoft Visual C++ 6.0

Visual C++ 6.0

mfc42.dll

MFC 6.0

1998年

內含於 Visual C++ 4.0

mfcce400.dll

MFC 6.0

Microsoft Visual C++ .NET 2002

Visual C++ .NET 2002 (Visual C++ 7.0)

mfc70.dll

MFC 7.0

2002年2月13日

Microsoft Visual C++ .NET 2003

Visual C++ .NET 2003 (Visual C++ 7.1)

mfc71.dll

MFC 7.1

2003年4月24日

Visual C++ .NET 2003 + MS11-025 (KB2465373)[7]

MFC 7.10.6119.0

2011年4月12日

Microsoft Visual C++ 2005

Visual C++ 2005 (Visual C++ 8.0)

mfc80.dll

8.0.50727.42

2006年4月10日

Visual C++ 2005 SP1

8.0.50727.762

2007年8月27日

Visual C++ 2005 SP1 + MS09-035 (KB973544)[8][9]

8.0.50727.4053

2009年7月28日

Visual C++ 2005 SP1 + MS11-025 (KB2467175)[7]

8.0.50727.5592

2011年4月12日

Visual C++ 2005 SP1 + MS11-025 (KB2538242)[7][10]

8.0.50727.6195 (包含於 redist 8.0.61000/8.0.61001[11])

2011年6月14日

Microsoft Visual C++ 2008

Visual C++ 2008 (Visual C++ 9.0)

mfc90.dll

9.0.21022.8

2007年11月19日

Visual C++ 2008 + MS09-035 (KB973551)[8][9]

9.0.21022.218

2009年7月28日

Visual C++ 2008 含Feature Pack

9.0.30411

2008年4月22日

Visual C++ 2008 SP1

9.0.30729.1

2008年8月11日

Visual C++ 2008 SP1 + MS09-035 (KB973552)[8][9]

9.0.30729.4148

2009年7月28日

Visual C++ 2008 SP1 + MS11-025 (KB2467174)[7]

9.0.30729.5570

2011年4月12日

Visual C++ 2008 SP1 + MS11-025 (KB2538243)[7]

9.0.30729.6161 (安裝程式版本 9.0.30729.5677)

2011年6月14日

Microsoft Visual C++ 2010

Visual C++ 2010 (Visual C++ 10.0)

mfc100.dll

10.0.30319.1

2010年4月12日[12]

Visual C++ 2010 + MS11-025 (KB2467173)[7]

10.0.30319.415

2011年4月12日

Visual C++ 2010 SP1

10.0.40219.1

2011年3月10日

Visual C++ 2010 SP1 + MS11-025 (KB2565063)[7]

10.0.40219.325

2011年8月9日

Microsoft Visual C++ 2012

Visual C++ 2012 (Visual C++ 11.0)

mfc110.dll

11.0.50727.1

2012年9月12日

Visual C++ 2012 Update 1

11.0.51106.1

2012年11月26日

Visual C++ 2012 Update 3

11.0.60610.1

2013年6月26日

Visual C++ 2012 Update 4

11.0.61030.0

2013年11月13日

Microsoft Visual C++ 2013

Visual C++ 2013 (Visual C++ 12.0)

mfc120.dll

12.0.21005.1

2013年10月17日

Visual C++ 2013 Update 2

12.0.30501.0

2014年5月12日

Visual C++ 2013 Update 5 + KB3138367

12.0.40649.5

2016年2月?

Visual C++ 2013 Update 5 + KB3179560

12.0.40660.0

2016年7月8日[13]

Visual C++ 2013 Update 5 + KB4032938

12.0.40664.0

2017年7月18日[14]

Microsoft Visual C++ 2015

Visual C++ 2015 (Visual C++ 14.0)

mfc140.dll

14.0.23026.0

2015年7月20日

Visual C++ 2015 Update 1

14.0.23506.0

2015年11月30日[15]

Visual C++ 2015 Update 2

14.0.23918.0

2016年3月30日[16]

Visual C++ 2015 Update 3

14.0.24210.0

2016年6月27日[17]

Visual C++ 2015 Update 3

14.0.24212.0

2016年8月18日

Visual C++ 2015 Update 3 + KB3165756

14.0.24215.1

2016年9月15日[18]

Microsoft Visual C++ 2017

Visual C++ 15.0

mfc140.dll

14.10.25008.0

2017年3月7日

Visual C++ 15.1?

14.10.25017.0

2017年4月5日?

Visual C++ 15.2

14.11.25325.0

2017年5月10日

Visual C++ 15.4

14.12.25810.0

2017年10月9日

Visual C++ 15.6

14.13.26020.0

2018年3月5日

Visual C++ 15.7

14.14.26405.0

2018年5月7日

Visual C++ 15.7.3?

14.14.26429.4

2018年5月31日

Visual C++ 15.8

14.15.26706.0

2018年8月14日

Visual C++ 15.9

14.16.27012.6

2018年11月13日

Visual C++ 15.9.5

14.16.27024.1

2019年1月8日

Visual C++ 15.9.6

14.16.27026.1

2019年1月24日

Visual C++ 15.9.9

14.16.27027.1

2019年3月12日

Visual C++ 15.9.15

14.16.27033.0

2019年8月13日

Microsoft Visual C++ 2019

Visual C++ 16.0.0

mfc140.dll

14.20.27508.1

2019年4月2日?

Visual C++ 16.1.0

14.21.27702.2

2019年5月21日

Visual C++ 16.2.0

14.22.27821.0

2019年7月24日

Visual C++ 16.3.0

14.23.27820.0

2019年9月23日

Visual C++ 16.4.0

14.24.28127.4

2019年12月3日

Visual C++ 16.5.0

14.25.28508.3

2020年3月16日

Visual C++ 16.6.0

14.26.28720.3

2020年5月19日

Visual C++ 16.6.3

14.26.28808.1

2020年7月30日

Visual C++ 16.7.0

14.27.29016.0

2020年8月5日

Visual C++ 16.7.5

14.27.29112.0

2020年9月29日

Visual C++ 16.8.0

14.28.29325.2

2020年11月10日

Visual C++ 16.8.2

14.28.29334.0

2020年11月19日

Visual C++ 16.9.0

14.28.29910.0

2021年3月2日

Visual C++ 16.9.2

14.28.29913.0

2021年3月16日

Visual C++ 16.9.4

14.28.29914.0

2021年4月13日

Visual C++ 16.10.0

14.29.30037.0

2021年5月25日

Visual C++ 16.10.2

14.29.30038.0

2021年6月15日

Visual C++ 16.10.4

14.29.30040.0

2021年7月20日

Visual C++ 16.11.0

14.29.30133.0

2021年8月10日

Visual C++ 16.11.4

14.29.30135.0

2021年10月5日

Microsoft Visual C++ 2022

Visual C++ 17.0.0RC

mfc140.dll

14.30.30704.0

2021年10月13日

1 Visual Studio速成版(Express)不包含MFC程式库。

2 Feature Pack只用于英文版本的Visual Studio 2008。非英文版本的支援於将包含于Visual Studio 2008 Service Pack 1。

MFC的结构[编辑]

作为一个应用程序的开发框架,必须满足各方面的功能需求。

应用程序启动[编辑]

基于MFC开发的应用程序在启动时,Windows操作系统:

首先调用WinMain函数(位于appmodul.cpp中,封装到mfc80.dll(VS2005版)),WinMain函数内调用了AfxWinMain函数。

AfxWinMain函数(位于WinMain.cpp中)调用了

该应用程序自定义的App类(这个类派生于CWinApp的,CWinApp又是派生于CWinThread,因此代表了应用程序的主线程)的InitInstance函数,该函数注册并创建窗口(通过AppUI2.cpp中的ProcessShellCommmand函数),然后ShowWindow、UpdateWindow;

CWinThread的InitInstance函数;

CWinThread的Run函数(位于thrdcore.cpp中)。该函数内部是Windows的消息循环。 当应用程序收到WM_QUIT消息后,CWinThread::Run函数返回,紧接着CWinThread::ExitInstance被调用,该函数可被覆盖。程序至此退出运行。 消息循环是一个for(;;)的死循环,该死循环内部包含了一个do...while的循环结构。while循环条件是调用PeekMessage函数的返回值,如果当前UI线程消息队列为空就返回到外层的死循环;while循环体内做两件事:

PumpMessage()。实际调用AfxInternalPumpMessage函数实现其功能:GetMessage()、AfxPreTranslateMessage()、TranslateMessage()、DispatchMessage().即:从UI线程消息队列移除一条消息、遍历该消息的CWnd类直到该窗口的各级别父窗口的CWnd类以提供预处理该消息的机会、如果该消息是按键消息则翻译为WM_CHAR消息、把该消息给相应的窗口函数。

IsIdleMessage():实际调用了AfxInternalIsIdleMessage函数,对于WM_PAINT、WM_SYSTIMER、以及光标位置没有变化的WM_MOUSEMOVE或WM_NCMOUSEMOVE,为Idle Message。

各个窗口函数(WndProc)内部首先获取对应当前窗口句柄的CWnd类的指针,然后调用AfxCallWndProc函数。

应用程序结束[编辑]

如果是点击了IDOK按钮,默认是调用OnOK(),然后是OnDestory(),最后是PostNcDestroy()

如果点击IDCANCEL按钮,默认调用OnCancel(),然后是OnDestory(),最后是PostNcDestroy()

如果点击右上角的关闭按钮:先OnClose(),然后是OnCancel(),再然后是OnDestory() ,最后是PostNcDestroy()

消息循环与消息映射[编辑]

参见:Windows消息循环

MFC Class hierarchy for Windows message process flow

消息分类[编辑]

分类

消息

映射宏

消息处理函数原型

注释

系统消息

标准Windows消息

MFC使用专用的相关的宏。如ON_WM_CREATE()

MFC使用专用的消息处理成员函数

一般地由窗口对象来处理这类消息

命令消息 WM_COMMAND

ON_COMMAND(id, memberFxn)

void OnXXX ()

通过标识符ID来区分来自哪个菜单项、工具栏按钮或者加速键等

ON_COMMAND_RANGE(id, idLast, memberFxn)

void OnXXX (UINT id)

批量处理一定范围内的标示符ID

ON_UPDATE_COMMAND_UI(id, idLast, memberFxn)

void OxXXX(CCmdUI* pCmdUI)

程序空闲时发的界面更新消息的宏

ON_UPDATE_COMMAND_UI_RANGE(id, idLast, memberFxn)

void OxXXX(CCmdUI* pCmdUI)

ON_CONTROL(id, idLast, memberFxn)

void OnXXX ()

父窗口响应控件发送的消息

ON_CONTROL_RANGE(id, idLast, memberFxn)

void OnXXX (UINT id)

ON_CONTROL_REFLECT(id, idLast, memberFxn)

void OnXXX ()

子控件响应父窗口反射回来的通知消息

通知消息WM_NOTIFY

ON_NOTIFY(wNotifyCode,id,memberFxn)

afx_msg void memberFxn(NMHDR * pNotifyStruct, LRESULT* result)

wParam为控件ID,lParam指向NMHDR结构体,结构体的code域值为控件通知码用来表示控件上的动作,如NM_CLICK.一般地由父窗口对象来处理这类消息。

ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )

可手工添加(class wizard不支持),处理控件id连续的一批控件的同一通知码消息。

ON_NOTIFY_EX

允许通知消息在多处被处理

ON_NOTIFY_EX_RANGE

ON_NOTIFY_REFLECT

afx_msg void memberFxn(NMHDR * pNotifyStruct, LRESULT* result)

复杂子控件响应父窗口反射回来的通知消息

自定义消息

窗口类内部自定义消息WM_USER到WM_APP-1

ON_MESSAGE(消息名,memberFxn)

afx_msg LRESULT OnMyMessageXXX(WPARAM wParam, LPARAM lParam)

示例

程序内部自定义消息WM_APP到0xBFFF

ON_THREAD_MESSAGE(WM_THREADMSG,OnThreadMessage)

afx_msg void OnThreadMessage(WPARAM wParam,LPARAM lParam);

示例

ON_REGISTERED_THREAD_MESSAGE

afx_msg void OnMyRegisterdThreadMsg(WPARAM, LPARAM);

RegisterWindowMessage()使用一个字符串来登记一个自定义的消息ID

应用程序之间自定义消息0xC000到0xFFFF

ON_REGISTERED_MESSAGE

LRESULT OnMyMessageXXX(WPARAM wParam, LPARAM lParam)

RegisterWindowMessage()使用一个字符串来登记一个自定义的消息ID,便于跨进程应用

控件的通知消息与反射消息[编辑]

窗体上的控件,应当向父窗体通报控件发生的各种事件,如被点击、绘制、内容改变等等,称为通知消息(notification message )。在 Windows 3.x的16位程序设计时代,控件向父窗体发送WM_COMMAND消息,由父窗体的代码负责实现这些事件。其中wParam的低16位是 control ID,高16位是notification code (例如BN_CLICKED);lParam是控件句柄。因此,再无可能传递其它信息给父窗体。为此,为传递具有特别内容的控件事件,Windows 3.x定义了一批特殊的通知消息(notification messages):

WM_PARENTNOTIFY:子窗口的某些重大事件发生时通知父窗口,包括创建、销毁、鼠标各键按下等事件

子窗口的滚动情况的通知消息

WM_VSCROLL

WM_HSCROLL

子窗口的绘制通知消息

WM_DRAWITEM,

WM_MEASUREITEM,

WM_COMPAREITEM,

WM_DELETEITEM,

WM_CHARTOITEM,

WM_VKEYTOITEM

WM_CTLCOLOR:设置按钮、编辑框、ListBox、Static、滚动条控件与MessageBox、DialogBox的前景色、背景色、背景模式、字体,并返回一把Brush,用于控件背景绘制。

早于4.0版本的MFC,在控件类提供了虚函数处理这些通知消息,这一办法已经被下述的“消息反射”取代(但仍然向后兼容继续支持)。

随着Windows 95开始了32位程序时代,伴之而来的是Win32 API 与 MFC 4.0。 Win32增加了很多复杂的控件,需要使用更多的通知消息传递很多复杂的数据给父窗体。Win32 API仅仅增加了一个消息WM_NOTIFY,就实现了这些功能。lParam参数开头是NMHDR数据结构,其后是与该通知类型相关的特定数据结构。

typedef struct tagNMHDR {

HWND hwndFrom;

UINT idFrom;

UINT code;

} NMHDR;

CWnd::OnNotify函数处理通知消息。它的默认实现是检查消息映射表(message map)查找通知的处理器函数并调用。一般说来,不必覆盖OnNotify;而应该写一个处理器函数并增加为该窗口类的消息映射表条目。

ON_NOTIFY(wNotifyCode, id, memberFxn)

成员函数应该写为:

afx_msg void memberFxn(NMHDR* pNotifyStruct, LRESULT* result);

MFC 4.0提供了一种特性“消息反射”(message reflection),[19]允许控件通知消息既可以在父窗口中,也可以在控件中被处理。可以对控件创建一个派生的控件类,实现对从父窗口反射回来的指定类型消息的处理。消息反射是MFC而不是Win32的特性,因此父窗口的类必须是从CWnd派生,从而父窗口在CWnd::OnNotify函数中处理控件的WM_NOTIFY时,首先调用CWnd::ReflectLastMsg把消息反射回控件的CWnd::SendChildNotifyLastMsg函数去处理;ReflectLastMsg返回值就是在控件的消息映射中使用ON_NOTIFY_REFLECT_EX()声明的反射消息处理函数的返回值,可以通知父窗口该消息是否已经被控件处理。控件的CWnd::SendChildNotifyLastMsg函数,首先获得线程的最后一条message,然后调用发送窗口的虚函数OnChildNotify函数。在子窗口处理反射回来的控件消息,第一种方法是重载控件窗口的OnChildNotify虚函数;第二种办法是由CWnd::OnChildNotify默认处理去调用CWnd::ReflectChildNotify函数,进入控件子窗口的MFC消息映射的标准处理(子窗口处理的消息被译成WM_REFLECT_BASE+WM_NOTIFY消息)。对于WM_NOTIFY,仅当在控件的消息映射(message map)中,控件没有通过ON_NOTIFY_REFLECT()声明的反射消息处理函数,父窗口的相应的通知消息处理函数才会被调用(在父窗口消息映射中使用宏ON_NOTIFY声明)。控件中通过ON_NOTIFY_REFLECT_EX()声明的反射消息处理函数可以返回真或假,以决定父窗口是否继续处理该通知消息。WM_NOTIFY以外的其它通知消息,父窗口在第一时间有机会处理它,控件对它的处理排在第二位。反射消息处理函数通常使用特定的名字,对应的消息反射宏的名字是在消息名字加上前缀ON_,后缀_REFLECT。如WM_CTLCOLOR对应ON_WM_CTLCOLOR_REFLECT。但以下三种情况,反射消息处理函数可以随意自行起名,对应的消息反射宏的名字分别为:

WM_COMMAND使用ON_CONTROL_REFLECT

WM_NOTIFY使用ON_NOTIFY_REFLECT

ON_UPDATE_COMMAND_UI使用ON_UPDATE_COMMAND_UI_REFLECT

消息传递处理机制[编辑]

MFC类体系中,Windows消息传递处理机制是基于CCmdTarget类及其派生类的静态成员函数GetThisMessageMap()内部定义的静态数据成员:

成员类型为AFX_MSGMAP_ENTRY的数组_messageEntries。在类的实现文件中,在BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间的内容来初始化消息映射入口项数组。

数据类型为AFX_MSGMAP的变量messageMap。该结构包含两项,分别是直接基类GetThisMessageMap函数指针与本类的_messageEntries数组首元素地址。

在头文件的类定义中使用宏DECLARE_MESSAGE_MAP()来声明静态成员函数GetThisMessageMap与虚函数GetMessageMap

用户所写的类的Windows消息处理函数(例如OnCommand)必须转换为CCmdTarget::*的成员函数指针类型AFX_PMSG,保存在该类的_messageEntries数组中。

struct AFX_MSGMAP_ENTRY

{

UINT nMessage; // windows消息代号

UINT nCode; // WM_NOTIFY的控制代码

UINT nID; // WM_COMMAND下面的ID号,如果为其他的消息,则这个数字为0

UINT nLastID; //和前面的ID一起组成一个范围,用于发送一次消息,处理执行多次

UINT nSig; // 标志消息处理函数的类型

AFX_PMSG pfn; // 函数调用指针

};

typedef void (CCmdTarget::*AFX_PMSG)(void);

调用用户类中该消息处理函数时,根据该函数保存在_messageEntries中的signature(一个无符号整型表示的函数的形参类型列表与返回值类型),把类型为void (CCmdTarget::*AFX_PMSG)(void)的成员函数指针强制转为其它类型的CCmdTarget成员函数指针(例如void (AFX_MSG_CALL CWnd::*pfn_v_i_i)(int, int),目前在union MessageMapFunctions中列出了近百种CCmdTarget成员函数指针),然后调用转换后的成员函数指针。这是基于Visual C++编译器把单继承的成员函数指针编译为只保存了函数的内存起始地址,因此可以在同一个单继承类中把一种类型的成员函数指针强制转换为另一种成员函数指针,或者把单继承派生类的成员函数指针强制转换为基类成员函数指针。这是打破了C++标准的违例办法。例如,对于CWnd::OnCommand函数,转换过程是:

BOOL (CWnd::*)(WPARAM, LPARAM lParam) => void (CWnd::*)() => void (CCmdTarget::*)()

CString[编辑]

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。

因此,每次为CString动态分配地址空间,实际分配长度为:(nChars+1)*nCharSize+sizeof(CStringData)。通过 Attach 操作,将这个 CStringData* 与 CSimpleStringT::m_pszData 执行了关联。当执行CString的默认构造函数生成一个空串时,实际上都是构造一个CnilStringData对象。CNilStringData 派生自 CStringData,额外拥有一个 achNil 的数组成员,这个数组初始化为空字符串。通过这个 achNil,保证了一个经过调用默认构造函数初始化的 CString,其指向的真正的字符串是一个空串。

部分编译器对std::string放弃了写时复制(Copy On Write)机制。但是,CString一直采取这一机制。CSimpleStringT::Fork 函数就提供了这样一个操作,具体分为下面几步:

根据传入的一个长度分配一段新的空间;—— Allocate(nLength, ...)

把旧数据拷贝到新的空间里面;—— CopyChars(...)

旧数据块的引用技术减1; —— pOldData->Release()

把 m_pszData 和新的数据块关联起来。—— Attach(pNewData)

GetString方法返回的是只读的字符串地址;而GetBuffer方法返回的是可写的字符串地址(如果数据区是共享的,则写时复制),如果修改了字符串内容,这时需要调用ReleaseBuffer方法把新的字符串长度修改到元数据中(并在尾部增加2个0字节)。[20]

CString对象用作可变参数函数(如printf)的实参时,由于无法通过形参类型确定调用哪个CString的类型转换操作符函数,因此有必要显式指明要转换的类型。如果需要在函数的参数传递CString,由于CString使用了引用计数,因此函数参数传递一个CString对象是可行的;不需要修改其内容时,推荐使用const CString&。

支持MFC的DLL开发[编辑]

使用Visual C++可以开发3种DLL:

不使用MFC的DLL;

使用MFC的规则的DLL:输出的函数不涉及MFC,因此可以被支持/不支持MFC的应用程序调用该DLL

动态链接到MFC(Regular DLLs dynamically linked to MFC)。

静态链接到MFC(Regular DLLs statically linked to MFC)

使用MFC的扩展DLL(Extension DLLs),只能动态链接到MFC:输出的函数涉及MFC,也可以输出基于MFC的派生类。

由于DLL与调用它的应用程序都可以有自己的MFC全局数据与句柄映射(handle mapping),如果句柄值相同,则默认使用应用程序的映射到的资源。为了不互相干扰,允许DLL内部使用自己的资源,必须在DLL函数的入口处把资源模块句柄从默认的应用程序切换为该DLL。办法是:

在该DLL的每个输出的函数的最开始之处调用AFX_MANAGE_STATE(AfxGetStaticModuleState( ))[21]。函数AfxGetStaticModuleState的功能是在运行栈上创建一个AFX_MODULE_STATE类的实例,对其进行设置,函数返回值为AFX_MODULE_STATE的指针。AFX_MODULE_STATE类利用其构造函数和析构函数进行模块状态现场存储及恢复。

使用AfxGetResourceHandle();获取当前资源模块句柄。使用AfxSetResourceHandle(HINSTANCE xxx); 设置程序要使用的资源模块句柄。

常用头文件与库文件[编辑]

STDAFX.H 载入其他MFC头文件。

AFXWIN.H 它和它载入的文件声明了所有的MFC类。其内包含AFX.H,后者包含了AFXVER_.H,后者又载入了AFXV_W32.H,后者又载入WINDOWS.H。

AFXEXT.H 使用工具栏、状态栏的程序必须载入这个文件

AFXDLGS.H 通用对话框(Common dialog)的MFC程序需要载入此文件。它内部包含COMMDLG.H

FXCMN.H 通用控件(common control)的MFC程序需要载入此文件。

AFXCOLL.H 使用MFC提供的容器都需要载入此文件。

AFXDLLX.H 凡使用MFC extension DLLs需要载入此文件。

AFXRES.H MFC程序的RC文件必须载入此文件。此文件中对于标准资源的ID都有默认值。它们定义于此文件中。

参考和引用[编辑]

^ MFC应用程序向导. [2011-05-18]. (原始内容存档于2016-04-02).

^ HOWTO:给ATL项目添加MFC支持. [2010-03-06]. (原始内容存档于2015-03-11).

^ Recommendations for Choosing Between ATL and MFC (页面存档备份,存于互联网档案馆)(英文)

^ Upgrading Relational Databases with Objects, Robert Vermeulen著, 126页

^ MFC Updates for Vista Common Controls. [2010-03-06]. (原始内容存档于2010-03-27).

^ Making your application sparkle with Windows 7. [2010-03-06]. (原始内容存档于2010-03-28).

^ 7.0 7.1 7.2 7.3 7.4 7.5 7.6 MS11-025: Vulnerability in Microsoft Foundation Class (MFC) Library could allow remote code execution: April 12, 2011. Microsoft.com. [June 10, 2019]. (原始内容存档于2019-07-02).

^ 8.0 8.1 8.2 Microsoft Security Bulletin MS09-035 - Moderate: Vulnerabilities in Visual Studio Active Template Library Could Allow Remote Code Execution (969706). Microsoft.com. [November 19, 2012]. (原始内容存档于2011-08-07).

^ 9.0 9.1 9.2 Protect your computer from the Active Template Library (ATL) security vulnerability. [October 29, 2010]. (原始内容存档于October 26, 2010).

^ Microsoft Visual Studio 2005 Service Pack 1 MFC Security Update. Microsoft.com. [November 19, 2012]. (原始内容存档于2011-08-20).

^ Where can I download Visual C++ Redistributables?. [June 10, 2019]. (原始内容存档于2019-04-19).

^ Visual C++ - Exploring New C++ and MFC Features in Visual Studio 2010. Msdn.microsoft.com. [November 19, 2012]. (原始内容存档于2019-01-13).

^ Update for Visual C++ 2013 and Visual C++ Redistributable Package. Msdn.microsoft.com. [January 8, 2017]. (原始内容存档于2021-01-16).

^ Update for Visual C++ 2013 Redistributable Package. [June 10, 2019].

^ Visual Studio 2015 Update 1. Msdn.microsoft.com. [June 12, 2016]. (原始内容存档于2016-07-17).

^ Visual Studio 2015 Update 2. Msdn.microsoft.com. [June 12, 2016]. (原始内容存档于2016-08-22).

^ Visual Studio 2015 Update 3. Msdn.microsoft.com. [June 28, 2016]. (原始内容存档于2017-10-21).

^ Microsoft Visual Studio 2015 Update 3 (KB3165756). Msdn.microsoft.com. [August 28, 2016]. (原始内容存档于2018-10-11).

^ MSDN TN062: Message Reflection for Windows Controls. [2017-08-01]. (原始内容存档于2017-08-01).

^ 《CString 的部分实现剖析》

^ MSDN:Module States of a Regular DLL Dynamically Linked to MFC. [2016-06-30]. (原始内容存档于2017-05-27).

ATL

Microsoft Visual Studio

Visual Studio .NET

Object Windows Library

查论编微軟應用程序開發介面與框架圖形介面

桌面窗口管理器

DirectX

Direct2D

Direct3D

D3DX

GDI / GDI+

WPF

Silverlight

WinRT XAML

Windows色彩系统

Windows Image Acquisition(英语:Windows Image Acquisition)

Windows Imaging Component(英语:Windows Imaging Component)

DXGI

Windows高级光栅化平台(WARP)

WinG标准

音樂與音效

DirectMusic

DirectSound

DirectX插件(英语:DirectX plugin)

跨平台音频创作工具(XACT)

Speech API(英语:Microsoft Speech API)

XAudio2(英语:XAudio2)

多媒體

DirectX

Media Objects

DXVA

Xinput

DirectInput

DirectShow

Image Mastering API

Managed DirectX(英语:Managed DirectX)

Media Foundation

XNA

Windows Media

Video for Windows

Web

MSHTML

RSS平台(英语:Windows RSS Platform)

JScript

VBScript

瀏覽器協助工具物件

XMLHTTP

SideBar小工具

TypeScript

資料存取

資料存取元件集

ADO

ADO.NET

Entity Framework

ODBC

OLE DB

可扩展存储引擎

WCF Data Services

同步框架(英语:Microsoft Sync Framework)

Jet資料庫引擎

微軟XML剖析器

OPC

網路

Winsock

LSP

Winsock内核(英语:Windows Vista networking technologies#Winsock Kernel)

Windows筛选平台

網路驅動程式介面規格(NDIS)

Windows Rally

后台智能传输服务(BITS)

對等通訊API(英语:Windows Vista networking technologies#Peer-to-peer communication)

MSMQ

MS MPI(英语:Microsoft Messaging Passing Interface)

DirectPlay

Active Directory Service Interface

通訊

訊息API(英语:Messaging Application Programming Interface)

電話API

WCF

管理

Win32控制台

Windows Script Host

WMI

PowerShell

工作排程器

Offline Files(英语:Windows Vista I/O technologies#Offline Files)

磁碟區陰影複製服務

Windows Installer

Windows錯誤回報

事件記錄器

通用日志文件系统

元件與模型

COM

COM+

ActiveX

DCOM

.NET框架

函式庫

框架类库

MFC

活动模板库(ATL)

WTL

驱动程序

WDM

WDF

KMDF

UMDF

WDDM

NDIS

UAA

BDA(英语:Broadcast Driver Architecture)

VxD

安全性

Crypto API

CAPICOM

Windows CardSpace

数据保护API

安全支持提供者接口(SSPI)

.NET

ASP.NET

ASP.NET AJAX

ADO.NET

Remoting

Silverlight

任务并行库(英语:Task Parallel Library)(TPL)

WCF

Windows CardSpace

WPF

WF

Core家族

.NET Core

ASP.NET Core

Entity Framework Core

ASP.NET Core MVC

软件工廠

EFx Factory(英语:EFx Factory)

Enterprise Library(英语:Microsoft Enterprise Library)

複合使用者介面(英语:Composite UI Application Block)

CCF(英语:Microsoft Customer Care Framework)

CSF(英语:Microsoft Connected Services Framework)

行程間通訊

MSRPC(英语:Microsoft RPC)

動態資料交換(DDE)

Remoting

WCF

可協助性

Active Accessibility(英语:Microsoft Active Accessibility)

使用者介面自動化(英语:Microsoft UI Automation)

文字與多語系支援

DirectWrite

文本服务框架(英语:Text Services Framework)

文本对象模型(英语:Text Object Model)

输入法

語言介面套件(英语:Language Interface Pack)

多语言用户界面

Uniscribe

遊戲開發

Direct3D

D3DX

DirectSound

DirectInput

DirectPlay

DirectMusic

Managed DirectX(英语:Managed DirectX)

XNA

查论编部件工具箱列表(英语:List of widget toolkits)低级AmigaOS平台

Intuition(英语:Intuition (Amiga))

Classic Mac OS和macOS平台未知/原生

Macintosh Toolbox(英语:Macintosh Toolbox)

Object Pascal

Carbon

CLI桌面

Xamarin.Mac(英语:Xamarin#Xamarin.Mac)

移动端

Xamarin.iOS

Windows平台

Windows API

UNIX平台X窗口系统

Xlib

XCB

X Toolkit Intrinsics、Xt、X-Toolkit

BeOS/Haiku平台

BeOS、ZETA、Haiku

跨平台CLI

OpenTK(英语:OpenTK)

C

GDK(英语:GDK)

Java

JOGL(英语:Java OpenGL)

Android平台CLI

Xamarin.Android

高级AmigaOS平台

BOOPSI(英语:BOOPSI)

MUI(英语:Magic User Interface)

ReAction GUI(英语:ReAction GUI)

Zune(英语:Zune (widget toolkit))

Classic Mac OS和macOS平台Object Pascal

Carbon

MacApp(英语:MacApp)

Objective-C桌面

Cocoa

移动端

Cocoa Touch

C++

MacZoop(英语:MacZoop)

PowerPlant(英语:PowerPlant)

Windows平台CLI桌面

Windows Forms

XAML(WinRT XAML、WPF)

C++

MFC

ATL

WTL

SmartWin++(英语:SmartWin++)

OWL

Object Pascal

VCL(英语:Visual Component Library)

UNIX平台X窗口系统

Athena (Xaw)

InterViews(英语:InterViews)

LessTif(英语:LessTif)

Motif

OLIT(英语:OLIT)

XForms(英语:XForms (toolkit))

Android平台C++

Qt for Android

跨平台按语言划分C

GTK+

IUP(英语:IUP (software))

Tk

wxC

XForms(英语:XForms (toolkit))

XVT(英语:XVT)

C++

CEGUI(英语:CEGUI)

CLX(英语:Component Library for Cross Platform)

FLTK

FOX toolkit(英语:Fox toolkit)

GLUI(英语:OpenGL User Interface Library)

Gtkmm

JUCE(英语:JUCE)

Nana(英语:Nana (C++ library))

Qt

Rogue Wave Views(英语:Rogue Wave Software)

TnFOX(英语:TnFOX)

Ultimate++(英语:Ultimate++)

VCF(英语:Visual Component Framework)

Wt(英语:Wt (web toolkit))

WxWidgets

YAAF(英语:YAAF)

Objective-C

GNUstep

CLI桌面

Gtk#

Tao(英语:Tao Framework)(OpenTK(英语:OpenTK)、TaoClassic(英语:TaoClassic))

wx.NET

UIML.NET(英语:UIML)

MonoGame(英语:MonoGame)

Web

Moonlight(英语:Moonlight (runtime))

移动端

MonoGame(英语:MonoGame)

Xamarin.Forms

D

DFL

DlangUI

DWT

GTK+

QtD

wxD

Flash

Apache Flex(MXML)

Haskell

Gtk2Hs

wxHaskell(英语:wxHaskell)

Java桌面

AWT

FXML(英语:FXML)(JavaFX)

Qt Jambi

Swing

SWT

wx4j

jUIML(英语:UIML)

Web

GWT

FXML(英语:FXML)(JavaFX)

移动端

LWUIT(英语:Lightweight User Interface Toolkit)

JavaScript

Dojo Toolkit

Echo

Extjs

Google Closure(英语:Google Closure Tools)

JQuery UI

Qooxdoo(英语:Qooxdoo)

YUI

Common Lisp

CAPI(英语:LispWorks)

CLIM(英语:Common Lisp Interface Manager)

McCLIM(英语:McCLIM)

Common Graphics(英语:Allegro Common Lisp)

Ltk

Lua

IUP(英语:IUP (software))

wxLua

Pascal桌面

LCL(英语:Lazarus Component Library)

移动端

LCL(英语:Lazarus Component Library)

Object Pascal桌面

CLX(英语:Component Library for Cross Platform)

fpGUI(英语:fpGUI)

IP Pascal(英语:IP Pascal)

LCL(英语:Lazarus Component Library)

移动端

LCL(英语:Lazarus Component Library)

Perl

Perl/Tk

PHP

PHP-GTK(英语:PHP-GTK)

PHP-Qt(英语:PHP-Qt)

wxPHP(英语:wxPHP)

Python

PyGTK

Pyjs(英语:Pyjs)

PyQt

PySide

Tkinter

WxPython

Ruby

Shoes

QtRuby

wxRuby

Tcl

Tcl/Tk

XML

Ample SDK(英语:Ample SDK)

GladeXML

Lively Kernel(英语:Lively Kernel)

Pyjs(英语:Pyjs)

Rialto Toolkit(英语:Rialto Toolkit)

XAML

XUI(英语:XML User Interface)

XUL

Wt(英语:Wt (web toolkit))

相关推荐

法国肯德基广告:高卢雄鸡,复刻进球庆祝名场面
金山卫镇
det365APP

金山卫镇

📅 06-29 👁️ 2913
衔的笔顺
det365APP

衔的笔顺

📅 06-27 👁️ 6797