1. 程式人生 > >Visual C++程式設計——MFC整理筆記

Visual C++程式設計——MFC整理筆記

In me the tiger sniffs the rose.”心有猛虎,細嗅薔薇。

人心擁有猛虎和薔薇的兩面體,若缺少了薔薇就難免變得莽撞,從而流入庸俗;若缺少了猛虎就難免變得懦弱,從而失去氣魄。

一、面向物件的概念

1、面向物件(Object-Oriented Program)更加符合人們認識世界實物的邏輯思維,更能充分使用和運用人們已經掌握的知識系統,尤其對於大型系統,函數語言程式設計難以描述傾城系統的架構,而面向物件則可解決這一問題,規模越大其體現的優勢也越大。

2、面向物件程式設計(OOP)是當前主流的程式設計範型,是一種程式語言模式,它已經取代了結構化、過程化程式設計開發技術,因為結構化的開發方法制約了軟體的可維護性和可擴充套件性。

3、面向物件程式設計的組織方式圍繞“物件”,而不是圍繞“行為”;圍繞“資料”,而非“邏輯”。

4、面向物件程式採用的觀點是“一切都是物件”。

5、在OOP中,物件的範圍囊括現實世界中客觀存在的實體(Entity),人類潛意識已經按照實體的共同或相似特性將其分類(Class),而通常見到的實體是某個類的一個例項(Instance)。

6、面向物件分析(OOA,Object-Oriented Analysis)就是以“類”的概念去認識問題、分析問題。

7、面向物件設計(OOD,Object-Oriented Design)是在OOA的基礎上進行資料建模,從而建立所要操作的物件以及它們之間的聯絡。

8、OOP則是在前兩者的基礎上,對資料模型進一步細化,定義它包含的資料的型別和任何能夠操作它的邏輯程式,每個不同的邏輯程式被認為是一個方法。

    實際應用中,一個類的現實例項被稱作一個“物件”,或者被稱作類的一個“例項”。

9、物件或者類例項是要在程式中使用和執行的,它的方法對應於計算機指令,它的屬性提供相應的資料,通過方法的呼叫來操作相應的資料,從而使資料得以保護,是開發者與資料隔離二無需獲知資料的具體格式。

10、面向物件程式語言有三個基本特徵:封裝、繼承和多型。

11、封裝

封裝就是把物件的屬性(狀態)和方法(行為)結合在一起,並儘可能隱蔽物件的內部細節,形成一個不可分割的獨立單位(即物件),對外形成一個邊界,只保留有限的對外介面使之與外部發生聯絡。

12、繼承

繼承是軟體重用的一種形式,它通過吸收現有類的資料(屬性)和方法,並增加新功能或修改現有功能來構建新類。

在C++語言中,通常稱一般類(如:“人”)為父類,也稱為超類;特殊類(如:“學生”和“老師”)成為子類,特殊類的物件擁有其一般類的全部屬性與方法。

13、多型

多型性是指在父類中定義的屬性或方法被子類繼承之後,可能具有不同的表現行為。這使得同一個屬性或方法在父類及其各個子類中具有不同的語義。

C++程式語言中可以通過子類對父類方法的重寫實現多型,也可以利用函式過載,在同一個類中定義多個函式名相同、引數不同的方法來實現多型。

多型的引入大大提高了程式的抽象程度和簡潔性,更重要的是它最大限度地降低了類和程式模組之間的耦合,提高了類模組的封閉性,使得他們不需要了解對方的具體細節,就可以很好地共同工作。

二、類的定義

1、C++中的類定義了一種新的資料型別。 多個物件所共有的屬性和操作需要組合成一個單元,稱為“類”,因此類是具有相同屬性和共同行為的一組物件的集合。

2、類一旦被定義,就可以用這種新型別來建立該型別的物件。累就是物件的模板,而物件就是類的一個例項。

3、類的屬性和方法如下:

   (1)類的屬性:物件的特徵在類中表示為成員變數,稱為類的屬性。例如,每一個僱員物件都有姓名、年齡和體重,它們是類中所有僱員共享的公共屬性。

   (2)類的方法:是類的成員函式,是物件執行操作的一種規範。方法指定以何種方式操作物件的資料,是操作的實際實現。

4、在C++中定義類的語法格式如下:

5、類的定義一般會用兩個檔案來實現:一個是類的定義檔案,在標頭檔案(.h)中實現;另一個是類的構造方法、成員函式的具體實現,用原始檔(.cpp)實現。在類的實現檔案中,類的成員函式的定義語法格式如下:

6、定義完一個類後,可以建立該型別的物件,即對該類進行例項化。如果想在建立物件時就能完成屬性的初始化操作,可通過類的特殊成員——建構函式。建構函式是物件建立時用於初始物件的特殊成員函式。

建構函式有兩點不同:

   (1)建構函式具有和它所在的類完全一樣的名字;

   (2)建構函式沒有返回型別;

7、建立物件有兩種方法:棧物件和堆物件

       棧物件離開作用域後,所佔記憶體由系統自動收回;

       堆物件在離開作用域後所佔記憶體並不會自動釋放,必須手動釋放,例如使用delete語句釋放new運算子所建立的堆物件。

8、在用派生類例項化物件時,基類和派生類的建構函式和解構函式的呼叫順序如下:

  (1)構造時,先呼叫基類的建構函式,然後是派生類的建構函式;

  (2)析構時,正好相反,先呼叫派生類的解構函式,然後是基類的解構函式。

9、this指標是指向一個物件地址的指標。this是一種隱含指標,它隱含於每個類的非靜態成員函式中,即每個非靜態成員函式都有一個this指標變數,this指標指向該成員函式所屬類的物件。

10、C++支援類的繼承。在C++中,被繼承的類叫基類或父類,繼承基類的類叫派生類或子類。

三、Win32程式設計

1、基於窗體的Windows應用程式,在32位CPU上,基於窗體的Windows程式稱為Win32程式。

2、應用程式如何通知作業系統執行某個功能呢?一般來說在應用中要完成某個功能,都是以函式呼叫的形式實現的。同樣的,應用程式也是以函式呼叫的方式通知作業系統執行相應的功能的,而且作業系統所能夠完成的每一個特殊功能通常都有一個函式與其對應,也就是說,作業系統把它所能夠完成的功能以函式的形式提供給應用程式使用,從而完成系統呼叫的目的,這些函式的集合就是Window作業系統提供給應用程式程式設計介面(API),簡稱

Windows API(Application Programming Interface)。如呼叫CreateWindow()函式,作業系統就會按照還函式提供的引數資訊在螢幕上產生一個相應的視窗。

3、要想使用Windows API開發程式,需要先安裝SDK(Software Development Kit),一般的IDE開發環境中都集成了SDK,如Visual Studio。

4、Windows SDK包括API函式宣告所在的標頭檔案、連結庫、幫助文件、輔助工具等,即SDK是開發程式所需資源的一個集合。

5、Windows程式採用的是事件驅動方式的程式設計模式,能被作業系統或者視窗感知、識別的操作稱為事件,作業系統通過訊息機制(Message)將感知到的事件傳遞給應用程式。

6、在應用程式啟動後,系統等待使用者在圖形使用者介面(窗體)內的輸入事件,如滑鼠按鍵、鍵盤按鍵、窗體建立、窗體關閉、窗體改變大小移動等,對系統而言這些都是事件。

7、作業系統將每個事件都包裝成一個稱為訊息的結構體MSG來傳遞給應用程式。只要有事件發生,系統即產生特定的訊息。

8、多位元組字符集(MBCS)、雙位元組字符集(UNICODE);

   SDK和MFC都能很好地同時支援MBCS、UNICODE。

   由於MBCS的字串表示是char*或char[],

   而UNICODE的字串表示是wchar_t*或wchar_t[];

9、為了方便程式設計,Windows新定義了資料型別TCHAR、LPTSTR、LPCTSTR,

   其中,TCHAR用來代替charwchar_t

         LPTSTRTCHAR*

   而LPCTSTRconst TCHAR*

API Application Programming Interface

10.、在Windows.h中,幾乎所有用於處理字串的API函式都使用TCHAR、LPTSTR、LPCTSTR三種資料型別。如果需要使用TCHAR等資料型別,在用SDK程式設計時需要包含tchar.h標頭檔案,並且const TCHAR*或LPCTSTR(常量字串)需要用到巨集“_T”。

四、源程式組成結構

1、Windows應用程式具有相對固定的基本結構,其中有入口函式WinMain()、視窗函式WndProc()構成基本框架,幷包含各種其他資料、函式等。入口函式和視窗函式是應用程式的主體。

2、入口函式WinMain()是所有Windows應用程式的入口,主要功能是註冊視窗類、建立顯示視窗以及產生訊息迴圈。

○定義視窗類物件;視窗的特徵是由WNDCLASS結構體來定義的;再結構體定義一個結構體物件,然後填寫相應的結構體成員,即可設計視窗特徵;

○註冊視窗類;視窗類物件定義完成後,需要呼叫RegisterClass()函式對其進行註冊;

○建立視窗例項;視窗類註冊完成後,就可以用CreateWindow()函式建立視窗類的例項了,也就是建立具體的視窗;

○顯示及更新視窗

3、CreateWindow()函式的原型如下:

CreateWindow()函式的dwStyle引數是具體要建立的視窗的樣式;

4、訊息迴圈,要從訊息佇列中取出訊息,需要呼叫GetMessage()函式,原型如下:

   只要從訊息佇列中取出的訊息不為WM_QUIT,GetMessage()函式返回的是一個非零值,否則返回0;

5、視窗函式,是完成WinMain函式的編寫後,還需要指定這個視窗的過程函式,又稱為回撥函式。

回撥函式處理原理:當應用程式收到某一視窗的訊息時,就應該呼叫某一函式來處理這條訊息,這一呼叫過程不用應用程式自己來實施,而由作業系統完成,但是,回撥函式本身的程式碼必須由應用程式完成。對於一條訊息,作業系統到底呼叫應用程式中的哪個函式來處理呢?於是Windows約定,由視窗的lpfnWndProc成員指定的函式來處理,應用程式的這個函式不是使用者自己呼叫的,而是寫好了程式處理邏輯,經由lpfnWndProc指定後,由作業系統完成呼叫。

視窗函式的名字有程式設計師定義,但要注意函式的返回值和引數表必須符合Windows作業系統的要求,視窗函式的原型如下:

 6、利用WNDCLASS類的lpfnWndProc()成員函式儲存的視窗函式指標呼叫視窗函式,已處理訊息。

五、GDI繪圖

1、GDI是圖形裝置介面(Graphic Device Interface)將物理顯示硬體和軟體程式分離、解耦,不允許程式直接訪問物理顯示硬體,而是通過稱為“硬體環境”的抽象結構間接訪問。

2、Windows應用程式中的所有繪圖操作,包括窗體本身的顯示都要呼叫GDI來實現。GDI處理來自Windows應用程式的圖形函式呼叫,然後把這些呼叫傳遞給合適的裝置驅動程式,由裝置驅動程式來執行與硬體(顯示卡)想過的操作併產生最後的輸出結果。

3、所有的繪製操作都是通過GDI中的裝置描述表(簡稱DC,裝置上下文,Device Context)進行的,裝置描述表對應的資料型別是HDC。HDC控制代碼是DC的資源識別符號。

4、Windows應用程式—》裝置描述表(DC)—》圖形裝置介面(GDI)—》裝置驅動程式。

六、MFC基礎

1、單純的使用Windows API進行程式設計時,大量的程式碼需要使用者自己編寫,工作量較大。利用MFC和嚮導來編寫Windows應用程式會簡化很多。

2、MFC(Microsoft Foundation Class Library)是微軟基礎類庫的簡稱。

3、MFC的目的就是讓程式設計師在MFC基礎上來建立Windows下的應用程式,MFC框架定義了應用程式的輪廓,並提供了使用者介面的標準實現方法,程式設計師所要做的就是通過預定義的介面把具體應用程式特有的東西填入這個輪廓。

4、CObject根類的最基本功能是支援序列化(serialization)、執行時(Run-time)類的資訊獲取、提供特定操作符以及完成物件的建立與刪除。

CObject派生類層次示意圖:

CObject根類(1、CCmdTarget類;

2、CDC裝置環境類;(CClientDC、CWindowDC、CPaintDC)

3、CGDiObject繪圖物件類;(CPen、Cbrush、CFont、CBitmap)

4、CMenu選單類;

5、Carray、Clist、Cmap…集合類;

6、Cdatabase、Crecordset…ODBC資料庫支援類;

7、CFile檔案類;)

5、CCmdTarget類(命令標靶類,command target)是MFC庫中所有具有訊息對映類的基類。CCmdTarget類還派生出了應用程式框架所需要的類。

CCmdTarget派生類層次示意圖:

CCmdTarget命令相關類(1、CWinThread執行緒類;(CWinApp應用程式類)            

2、CDocument文件類;

3、CDocTemplate文件模板類;(CSingle/MultiDocTemplate單/多文件模板類)

4、CWnd視窗類;(CFrameWnd框架視窗類、CView檢視類、CDialog對話方塊類))

6、將訊息和表格中的元素比較,然後呼叫對應的處理程式,這種操作稱為訊息對映(MessageMapping)。

7、文件是應用程式資料基本元素的集合,它構成應用程式所使用的資料單元;

   檢視是資料顯示單元。

   Windows作業系統提供的記事本程式就是單文件程式;

   Word程式就是多文件程式;

8、序列化是指將物件儲存到儲存介質上(比如磁碟)或從儲存介質讀取並重新構造物件的過程。

   CObject類定義了兩個在序列化過程中起重要作用的成員函式:Serialize()函式和IsSerializable()函式。

   Serialize()函式用於將物件序列化;

   IsSerializable()函式用於確定該物件是否支援序列化操作;

9、CDialog是對Windows對話方塊的封裝。可以直接使用CDialog類例項化物件然後呼叫相關成員的成員函式以建立對話方塊。

   CDialog還派生了一個CCommonDialog類。該類有派生了一些用於特殊用途的對話方塊,這些類提供了標準的Windows對話方塊支援,例如

△ CFileDialog:開啟或儲存檔案對話方塊類;

△ CColorDialog:選擇顏色對話方塊類;

△ CFontDialog:選擇字型對話方塊類;

△ CPrintDialog:列印檔案對話方塊類;

△ CFindReplaceDialog:查詢、替換操作對話方塊類;

10、GDI是Windows影象裝置介面,使用GDI直接繪圖比較繁瑣,MFC對GDI操作進行了進一步的封裝,簡化了使用方法。封裝主要體現在三個方面:

(1)CDC(DC,裝置描述表)及其派生類;

(2)圖形物件類;

(3)繪圖有關的資料型別;

11、// 建立新筆(實線/虛線,1個/2個畫素寬,顏色)

CreatePen(PS_SOLID/PS_DASH,1/2,RGB(255,255,255))

12、combinator:協調器、連線符、組合子

13、MFC對GDI繪圖物件的封裝給使用帶來了方便,可以呼叫建構函式或成員函式物件,並設定物件屬性(顏色),物件被銷燬時解構函式會自動釋放做佔用的系統記憶體。

MFC繪圖物件類的主要成員函式及功能

物件

MFC

建立方法

畫筆

CPen

呼叫建構函式或CreatePen()和CreatePenIndirect()成員函式

畫刷

CBrush

呼叫建構函式或CreateBrushIndirect()、CreateSolidBrush()等函式

字型

CFont

呼叫CreateFont()、CreateFontIndirect()等成員函式

點陣圖

CBitmap

一般呼叫LoadBitmap()函式從資源中載入點陣圖

調色盤

CPalette

呼叫CreatePalette()或CreateHalftonePalette()成員函式

區域

CRgn

呼叫以Creae開頭的成員函式

在使用MFC繪圖物件時要遵守一定的規則:

  • 建立物件:呼叫建構函式例項化物件,若建構函式沒有建立相應的GDI物件,則要呼叫成員函式進一步建立。
  • 呼叫CDC類的SelectObject選入DC;
  • 呼叫CDC類的成員函式繪圖;
  • 恢復原來的物件;

物件離開作用域,自動釋放繪圖物件,進一步有系統自動實現;

七、MFC文件/檢視

1、文件/檢視結構是MFC中結構最複雜、體系最龐大而又最富有的特色的部分。

  Document/View也被稱為Model-View_Controller(MVC)文件檢視模板;

2、Document在MFC的CDocument中被例項化,用來承載(容納)資料,並至少提供專門負責檔案讀/寫操作的Serialize函式的類;

  View負責描述或呈現Document中的資料,它有兩個最重要的任務:一是負責資料的顯示;

另一個是負責資料的編輯。

3、文件/檢視結構簡單化了多數應用程式的設計開發過程,主要的優點試講資料操作、資料顯示和使用者介面分離開;

  MFC在文件/檢視結構上提供了許多標準操作(如新建檔案、開啟檔案、儲存檔案、列印等操作),它們被框架自動完成,減輕了開發者的工作量,不必編寫這些程式碼,從而可以把更多的精力放到應用程式特定功能的程式碼上。

4、MFC將文件/檢視程式分為兩類:單文件程式(SDI)和多文件程式(MDI)。

5、△ CWinApp類:應用程式類,是非窗體類。該類的派生類例項化一個全域性物件。CWinApp類物件是應用程式的起點,負責應用程式的啟動。

  △ CFrameWnd類:框架視窗類,是應用程式的框架視窗。所謂框架視窗是指包括選單、工具欄、狀態列和視窗客戶區的整個應用程式的主視窗。該類的派生類物件是在InitInstance()函式內例項化的。

  △ CView類:檢視視窗類,專門用來對應用程式的資料進行顯示。檢視類中有一個很重要的成員函式OnDraw(),已完成檢視類的資料顯示工作。

  △ CDocument類:文件類,是非窗體類。

  △ CDocTemplate類:文件模板類,是非窗體類。其作用是建立文件/檢視結構中的文件類、檢視類和框架視窗類之間的關係