C、C++控制檯程序、Windows API程序、MFC程序理解與比較

在編程語言中,函數是一個很重要的概念,其身影無處不在。在面向過程的編程方式中,函數更是程序的基本構建模塊,在面向對象的編程方式中,函數演變為類或對象的成員(當然也可以使用與類無關的函數)。

函數由函數頭和函數體組成。函數頭包括域屬性(如external、static或類域)、返回值類型、函數名、及參數。域屬性包括其在多文件編程中的可見範圍,是否是屬於某一個類的成員?返回值類型是指函數返回的值的具體數據類型(可以理解為函數輸出的一部分)。函數名是函數保存在內存代碼區的首地址,用於函數的調用及函數指針的右值。參數可以理解為函數的輸入、輸出(如果是引用或指針作為參數,可以理解為是一個種輸出,因為其操作或更新的數據是引用或指針的地址值所指向的內存單元)。在C\C++中,函數體位於{}中,函數體是函數功能的具體實現。

如果用一臺手機來理解函數概念,手機裸露在外的操作界面就像是函數頭,外殼內的組件就像是函數體中,外殼就像是{}。

函數的開發者和使用者可以站在不同的角度去理解函數的構造,函數的開發者需要負責函數頭作為界面(interface)的友好性及穩定性,以及保證實現(implement)函數功能的函數體的空間和時間效率。而函數的使用者可以不關心函數功能的具體實現(當然瞭解其具體實現能更好地加深對函數的理解),也就是不心關心函數體的具體內容,只需關心函數使用的具體細節,也就是函數體的內容。

就如同一臺手機,手機開發者要負責手機從外部操作到內部零部件的全部,而手機購買者(使用者)則只需關心怎樣使用即可。

一個數據集D,以及操作這個數據集D的代碼集C如何更好地形成一個整體,在函數的概念中有一定的體現,也就是通過參數和局部變量形成數據集D,以及在函數體中包含一個函數指針,由其指向的函數代表代碼集C。但這種封裝性還是體現得不夠充分。如果把數據集D,以及操作這個數據集D的代碼集C全部歸屬(或限定)到某一個類別,並設定訪問控制(access modifier)的概念,這種封裝性就能得到最充分的體現,這種思想就是面向對象的類類型概念。訪問控制就像一個手機外殼,用public修飾的類(對象)的屬性(數據集D)或方法(代碼集C)就是一個類(對象)提供的界面(interface),是公共的,公開的,裸露在外的,使用者密切關注的;而private修飾的類(對象)的屬性(數據集D)或方法(代碼集C)就是一個類(對象)提供的具體實現,是私密的,隱藏在內的,使用者可以不加以密切注意的。

於是,一些編程大牛對於一些使用頻率很高的功能便開發出界面友好穩定、實現效率高的函數和類,保存在庫(library)中,也就是函數庫或類庫,實現共享。一些優秀函數庫或類庫也就成了編程語言的有機組成部分。

一種計算機語言的應用程序是運行在某一操作系統之上的,某一操作系統對某一語言的支持是通過其某一語言的函數庫或類庫來實現的。

1 控件臺程序

控制檯程序程序只關心數據,不在乎界面,在一個簡單的Shell中執行。

控制檯程序用字符進行交互,不需要鼠標操作,也就是沒有圖形界面,也就是不需要使用控件做為輸入、輸出的媒介。

而window api與MFC主要使用控件(視窗)做為交互媒介,也就有了資源對象(不是類類型對象)的概念,同時也有了事件消息和消息響應函數的概念(Message Based,Event Driven)。

2 Windows API編程

當Windows操作系統開始佔據主導地位的時候,開發Windows平臺下的應用程序成為人們的需要。而在Windows程序設計領域處於發展的初期,Windows程序員所能使用的編程工具唯有API(Application Programming Interface)函數,這些函數是Windows提供給應用程序與操作系統的接口,他們猶如“積木塊”一樣,可以搭建出各種界面豐富,功能靈活的應用程序。所以可以認為API函數是構築整個Windows框架的基石,在它的下面是Windows的操作系統核心,而它的上面則是所有的華麗的Windows應用程序。

Windows API所提供的功能可以歸為七類:

2.1 基礎服務(Base Services),提供對Windows系統可用的基礎資源的訪問接口。比如像:文件系統(file system)、外部設備(device)、進程(process)、線程(thread)以及訪問註冊表(Windows registry)和錯誤處理機制(error handling)。這些功能接口位於Windows下的 kernel32.dll和advapi32.dll中。

2.2 圖形設備接口(GDI),提供功能為:輸出圖形內容到顯示器、打印機以及其他外部輸出設備。位於Windows下的gdi32.dll。

2.3 圖形化用戶界面(GUI),提供的功能有創建和管理屏幕和大多數基本控件(control),比如按鈕和滾動條,接收鼠標和鍵盤輸入,以及其他與GUI有關的功能。這些調用接口位於Windows下的user32.dll。從Windows XP版本之後,基本控件和通用對話框控件(Common Control Library)的調用接口放在comctl32.dll中。

2.4 通用對話框鏈接庫(Common Dialog Box Library),為應用程序提供標準對話框,比如打開/保存文檔對話框、顏色對話框和字體對話框等等。這個鏈接庫位於Windows下comdlg32.dll中。它被歸類為User Interface API之下。

2.5 通用控件鏈接庫(Common Control Library),為應用程序提供接口來訪問操作系統提供的一些高級控件。比如狀態欄(status bar)、進度條(progress bars)、工具欄(toolbar)和標籤(tab)等。這個鏈接庫位於Windows下comctl32.dll中。它被歸類為User Interface API之下。

2.6 Windows外殼(Windows Shell),作為Windows API的組成部分,不僅允許應用程序訪問Windows外殼提供的功能,還對之有所改進和增強。它位於Windows下的shell32.dll中(Windows 95則在 shlwapi.dll中)。 它被歸類為User Interface API之下。

2.7 網絡服務(Network Services),為訪問操作系統提供的多種網絡 功能提供接口。它包括NetBIOS、Winsock、NetDDE及RPC等。

3 從API到可視化編程

程序員想編寫具有Windows風格的軟件,必須藉助API,API也因此被賦予至高無上的地位。但是,如若沒有合適的Windows編程平臺,那麼Windows開發是一項很複雜的工作。在可視化編程IDE出來之前,那時的Windows程序開發還是比較複雜的工作,程序員必須熟記一大堆常用的API函數,而且還得對Windows操作系統有深入的瞭解。然而隨著軟件技術的不斷髮展,在Windows平臺上出現了很多優秀的可視化編程環境,程序員可以採用“所見即所得”的編程方式來開發具有精美用戶界面和功能強大的應用程序。

這些優秀可視化編程環境操作簡單、界面友好(諸如VB、VC++、DELPHI等),在這些工具中提供了大量的類庫和各種控件,它們替代了API的神祕功能,事實上這些類庫和控件都是構架在WIN32 API函數基礎之上的,是封裝了的API函數的集合。它們把常用的API函數的組合在一起成為一個控件或類庫,並賦予其方便的使用方法,所以極大的加速了Windows應用程序開發的過程。有了這些控件和類庫,程序員便可以把主要精力放在程序整體功能的設計上,而不必過於關注技術細節。

4 API編程適應場合

實際上如果我們要開發出更靈活、更實用、更具效率的應用程序,必然要涉及到直接使用API函數,雖然類庫和控件使應用程序的開發簡單的多,但它們只提供Windows的一般功能,對於比較複雜和特殊的功能來說,使用類庫和控件是非常難以實現的,這時就需要採用API函數來實現。

這也是API函數使用的場合,所以我們對待API函數不必刻意去研究每一個函數的用法,那也是不現實的(能用得到的API函數有幾千個呢)。正如某位大蝦所說:API不要去學,在需要的時候去查API幫助就足夠了。但是,許多API函數令人難以理解,易於誤用,還會導致出錯,這一切都阻礙了它的推廣。

5 從API到MFC

數以千計的Windows APIs,每個看起來都好象比重相若(至少你從手冊上看不出來孰輕孰重)。有些APIs 彼此雖有群組關係,卻沒有相近或組織化的函數名稱。星羅棋佈,霧列星馳;又似雪球一般愈滾愈多,愈滾愈大。撰寫Windows 應用程序需要大量的耐力與毅力,以及大量的小心謹慎!

MFC 幫助我們把這些浩繁的APIs,利用對象導向的原理,邏輯地組織起來,使它們具備抽象化、封裝化、繼承性、多態性、模塊化的性質。

1989 年微軟公司成立Application Framework 技術團隊,名為AFX 小組,用以開發C++對象導向工具給Windows 應用程序開發人員使用。AFX 的"X" 其實沒有什麼意義,只是為了湊成一個響亮好唸的名字。

這個小組最初的「憲章」,根據記載,是要"utilize the latest in object oriented technology toprovide tools and libraries for developers writing the most advanced GUI applications on themarket",其中並未畫地自限與Windows 操作系統有關。果然,其第一個原型產品,有自己的窗口系統、自己的繪圖系統、自己的對象數據庫、乃至於自己的內存管理系統。當小組成員以此產品開發應用程序,他們發現實在是太複雜,又悖離公司的主流系統--Windows -- 太遙遠。於是他們修改憲章變成"deliver the power of object-oriented solutionsto programmers to enable them to build world-class Windows based applications in C++." 這差不多正是Windows 3.0 異軍崛起的時候。

C++ 是一個複雜的語言,AFX 小組預期MFC 的使用者不可能人人皆為C++ 專家,所以他們並沒有採用所有的C++ 高階性質(例如多重繼承)。許多「麻煩」但「幾乎一成不變」的Windows 程序動作都被隱藏在MFC 類別之中, 例如WinMain 、RegisterClass、Window Procedure 等等等。

為了讓MFC 儘可能地小,儘可能地快,AFX 小組不得不捨棄高度的抽象(導至過多的虛擬函數),而引進他們自己發明的機制,嘗試在對象導向領域中解決Windows 消息的處理問題。這也就是Message Mapping 和Message routing 機制。注意,他們並沒有改變C++ 語言本身,也沒有擴大語言的功能。他們只是設計了一些令人拍案叫絕的宏,而這些宏背後隱藏著巨大的機制。

微軟公司於1992/04 推出C/C++ 7.0 產品時初次向世人介紹了MFC 1.0,這個初試啼聲的產品包含了20,000 行C++ 源代碼,60 個以上的Windows 相關類別,以及其它的一般類別如時間、數據處理、文件、內存、診斷、字符串等等等。它所提供的,其實是一個"thin and efficient C++ transformation of the Windows API"。其32 位版亦在1992/07 隨著Win32 SDK 推出。

MFC實現了控件的可視化,其application Wizard和class wizard可以實現程序和代碼模塊框架的自動化實現。

C、C++控制檯程序、Windows API程序、MFC程序理解與比較

開發需要讀寫文件的應用程序並且有簡單的輸入和輸出可以利用單文檔視結構。

開發注重交互的簡單應用程序可以使用對話框為基礎的窗口,如果文件讀寫簡單這可利用CFile進行。

在要求在多個文檔間傳遞數據時使用多文檔視結構。

C、C++控制檯程序、Windows API程序、MFC程序理解與比較

6 圖形界面程序中的資源

資源在Windows API中使用一種特殊的結構體指針,句柄來引用。

Windows API開發之初C++還沒有出現,所以windows提供的API函數使用的封裝數據類型是結構體(不是類)。隨著C++的誕生與普及,Windows API+C++就誕生了MFC,且資源控件開發實現了可視化,而封裝數據類型也用類類型來實現。

C、C++控制檯程序、Windows API程序、MFC程序理解與比較

常用的資源:ICON、CURSOR、BITMAP、FONT、DIALOG、MENU、ACCELERATOR、STRING、VERSIONINFO、TOOLBAR。

C、C++控制檯程序、Windows API程序、MFC程序理解與比較

7 圖形界面程序中的事件與消息

Windows API是編程者自己把消息和響應函數聯繫在一起。mfc是編程者採用微軟為我們做好了MESSAGE-MAP機制,來處理消息。

8 函數庫和類庫

Windows API和MFC都使用 .lib 文件。

.lib 分兩種, 一種是 .lib 文件裡面包含了 cpp 編譯出來的代碼, 鏈接的時候把需要的代碼拷貝到 exe 裡面,mfc,、crt在選擇靜態的時候使用這種方式。

另外一種是.lib中不包含代碼, 只是描述該到哪個dll裡面怎麼找對應的代碼. 這種編譯出來的exe就需要dll一起才能運行。mfc、crt使用共享庫的時候, 以及 Windows API 就是使用的這種方式。

API 的 dll 在 windows 系統的 system32 目錄下, 圖形界面相關的 API 在 USER32.dll 裡,進程、文件之類的操作在 kernel32.dll 裡。MSDN 的每個函數都會說明它在哪個頭文件, 哪個 lib, 哪個 dll 裡的。

9 C、C++控制檯程序、Windows API程序、MFC程序比較

C、C++控制檯程序、Windows API程序、MFC程序理解與比較

C++ 並不是純種的對象導向語言(SmallTalk 和Java 才是)。所以,MFC之中得以存在有不屬於任何類別的全域函數,它們統統在函數名稱開頭冠以Afx。

SDK 程序只要包含WINDOWS.H 就好,所有API 的函數聲明、消息定義、常數定義、宏定義、都在WINDOWS.H 檔中。除非程序另調用了操作系統提供的新模塊(如CommDlg、ToolHelp、DDEML...),才需要再各別包含對應的.H 檔。

C、C++控制檯程序、Windows API程序、MFC程序理解與比較

關於類的繼承性在MFC的控件類中有最充分的體現,在MFC中,各種控件類的框架都已搭建好,其中包含了最通用的屬性和方法以及一些虛函數,開發者可以重寫虛函數或派生控件類來實現自己的功能或個性化的需求。

-End-

相關推薦

推薦中...