Can you summarize the following document?
        
  Visual C++包含MFC應用程式嚮導,可用於相容MFC的應用程式。在ATL程式中也可以手動新增MFC支援。在嚮導中有各種選項以定製生成的程式的功能,例如介面風格、語種、資料庫開發支援、列印支援、自動化支援、ActiveX支援、網路支援、基於HTML的幫助文件支援等等。  在COM開發方面,相對於ATL來說,MFC的元件比較大,程式碼不夠短小精悍,但是支援的功能也比較多,例如有對ActiveX Document的封裝類。  在介面開發方面,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)。  隨著Visual Basic和Visual Studio.NET的釋出,曾經一度被微軟重點推薦的MFC被Visual Basic.NET、C#、Windows Forms搶走了不少市場份額,但是MFC繼續在非託管軟體開發中佔據重要地位。在託管開發方面,MFC中也包括對Windows Forms和託管/非託管互操作的封裝。微軟在Windows Vista和Windows 7釋出之後在MFC中增加了對新的Windows API支援。

  MFC的主要優點是可以用物件導向的方法來呼叫Windows API,以及能夠更加便捷地開發應用程式。MFC將很多應用程式開發中常用的功能自動化,並且提供了文件框架檢視結構和活動文件這樣的便於自定義的應用程式框架。同時,在Visual C++內部也內建了很多對MFC的例如類嚮導這樣的支援以減少軟體開發的時間,使用類嚮導可以快速生成Hello World程式。

  雖然MFC的原始碼對使用者是完全開放的,但是MFC的一些封裝過程過於複雜,以致於新使用者很難迅速掌握MFC的應用程式框架,以及在除錯中定位問題的位置。同時,很多MFC物件不是執行緒安全的,致使在跨執行緒訪問MFC物件時需要編寫額外的程式碼。另外,MFC的很多類依賴於應用程式嚮導生成的程式碼,使得在使用Visual C++中其他型別的應用程式嚮導生成的工程中新增MFC支援的難度大大增加。

  很多商用類庫在MFC的基礎上進一步實現了面板、漸變風格、多頂層視窗程式、屬性列表等較受歡迎的功能;同時,在C++線上社群中,很大一部分開放的原始碼也是基於MFC的。

  作為一個應用程式的開發框架,必須滿足各方面的功能需求。

  基於MFC開發的應用程式在啟動時,Windows作業系統:

  

  窗體上的控制元件,應當向父窗體通報控制元件發生的各種事件,如被點選、繪製、內容改變等等,稱為通知訊息(notification message )。在 Windows 3.x的16位程式設計時代,控制元件向父窗體傳送WM_COMMAND訊息,由父窗體的程式碼負責實現這些事件。其中wParam的低16位是 control ID,高16位是notification code (例如BN_CLICKED);lParam是控制元件控制代碼。因此,再無可能傳遞其它資訊給父窗體。為此,為傳遞具有特別內容的控制元件事件,定義了一批特殊的通知訊息(notification messages): 早於4.0版本的MFC,在控制元件類提供了虛擬函式處理這些通知訊息,這一辦法已經被下述的“訊息反射”取代。  隨著Windows 95開始了32位程式時代,伴之而來的是Win32 API 與 MFC 4.0。 Win32增加了很多複雜的控制元件,需要使用更多的通知訊息傳遞很多複雜的資料給父窗體。Win32 API僅僅增加了一個訊息WM_NOTIFY,就實現了這些功能。lParam引數開頭是NMHDR資料結構,其後是與該通知型別相關的特定資料結構。  MFC 4.0提供了一種特性“訊息反射”(message reflection),允許控制元件通知訊息既可以在父視窗中,也可以在控制元件中被處理。可以對控制元件建立一個派生的控制元件類,實現對從父視窗反射回來的指定型別訊息的處理。訊息反射是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。但以下三種情況,反射訊息處理函式可以隨意自行起名,對應的訊息反射巨集的名字分別為:

  MFC類體系中,Windows訊息傳遞處理機制是基於CCmdTarget類及其派生類的靜態成員函式GetThisMessageMap()內部定義的靜態資料成員: 在標頭檔案的類定義中使用巨集DECLARE_MESSAGE_MAP()來宣告靜態成員函式GetThisMessageMap與虛擬函式GetMessageMap  使用者所寫的類的Windows訊息處理函式(例如OnCommand)必須轉換為CCmdTarget::*的成員函式指標型別AFX_PMSG,儲存在該類的_messageEntries陣列中。  呼叫使用者類中該訊息處理函式時,根據該函式儲存在_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函式,轉換過程是:

  CString是MFC中最常見的類之一,用於封裝字串資料結構。它只有一個資料成員m_pszData,其值為字串的首地址,其資料型別為wchar_t*或char*。在CString的m_pszData的前面實際還分配了CSringData資料塊,包含了codice_1等管理資料。CAtlStringMgr提供記憶體管理,CStringData提供共享管理。而更上層的CString提供字串操作。CAtlStringMgr的一個成員是IAtlMemMgr介面,這是策略模式,可以引用某個記憶體管理類。CAtlStringMgr的另一個成員是CNilStringData。  因此,每次為CString動態分配地址空間,實際分配長度為:codice_2。當執行CString的預設建構函式生成一個空串時,實際上都是構造一個CnilStringData物件。  部分編譯器對std::string放棄了寫時複製(Copy On Write)機制。但是,CString一直採取這一機制。GetString方法返回的是隻讀的字串地址;而GetBuffer方法返回的是可寫的字串地址,如果修改了字串內容,這時需要呼叫ReleaseBuffer方法把新的字串長度修改到後設資料中。  CString物件用作可變引數函式(如printf)的實參時,由於無法通過形參型別確定呼叫哪個CString的型別轉換操作符函式,因此有必要顯式指明要轉換的型別。如果需要在函式的引數傳遞CString,由於CString使用了引用計數,因此函式引數傳遞一個CString物件是可行的;需要修改其內容時,推薦使用const CString&。

  使用Visual C++可以開發3種DLL:  由於DLL與呼叫它的應用程式都可以有自己的MFC全域性資料與控制代碼對映(handle mapping),如果控制代碼值相同,則預設使用應用程式的對映到的資源。為了不互相干擾,允許DLL內部使用自己的資源,必須在DLL函式的入口處把資源模組控制代碼從預設的應用程式切換為該DLL。辦法是:
微軟基礎類庫(英語:Microsoft Foundation Classes,簡稱MFC)是一個微軟公司提供的類庫(class libraries),以C++類的形式封裝了Windows API,並且包含一個(也是微軟產品的唯一一個)應用程式框架,以減少應用程式開發人員的工作量。其中包含的類包含大量Windows控制代碼封裝類和很多Windows的內建控制元件和元件的封裝類。