一、基於Microsoft MFC的編程方法
MFC是微軟基礎類庫(Microsoft Foundation Class)的縮寫。與API不同,MFC不是Windows操作系統的組成部分,而是微軟公司專為VC++開發的配套軟件包。與VC6配套的是MFC6.0。MFC充分使用了面向對象方法中的繼承和多態性技術,以類的方式封裝了Windows應用程序所涉及的幾乎所有的標准部件,如Windows應用程序的架構、各種標准的圖形界面元素、其核心是它以C++的形式封裝了Windows API的大部分函數。
MFC是一個很大的類層次體系(MFC6.0中包含了200多個類),它由一個稱為CObject的類作為根基類,其他類大部分從該類派生而來,其整個類體系可大致划分為:
■基類
■應用程序框架類。 包括:應用程序類、命令類、文檔/視窗類、框架窗口類、文檔模板類等
■可視對象類。 包括:窗口類、對話框類、控件類等
■繪圖類。 包括:繪圖工具類、設備描述表類等。
■簡單數據類型類
■通用類 包括:數組類、類表類、映像類
■文件和數據庫類 包括:文件I/O類、ODBC類、ADO類
■Internet和網絡工作類 包括:Win32 Internet類、Windows Socket類等
■對象鏈接和嵌入(OLE, Object Lingking and Embedding)類
■調試和異常類
事實上,MFC封裝了一個Windows應用程序操作的每一方面,因此使用MFC編程,編程者可以把注意力集中於自己程序所特有的部分,不需要事事親自動手。與直接調用API函數相比,這將大大減少編程者編寫的代碼數量,使編程工作變得更容易;同時,程序標准部分由MFC的類來提供,可使程序變得更規范,更具可讀性,效率也更高。
二、實例講解
閑話不多扯,下面說下這個實例怎么用VC++實現。我用的編譯器是vc++6.0。
首先知道步驟:
開發一個MFC項目通常有四個步驟:
Step.1 建立項目架構
Step.2 設計圖形用戶界面
Step.3 設計對象的事件驅動程序
Step.4 項目的編譯、鏈接和運行
第一步呢,建立項目架構,如圖:


后面一系列默認步驟,最后出現:


下面便到了第二步,設計用戶圖形界面,就是玩玩控件。
可在對話框上建立(拖拽)如下控件:
■1個編輯框:用於用戶輸入半徑值;
■5個靜態文本框(靜態文本框只能顯示文本而不能輸入文本),其中:2個靜態文本框分別用於顯示圓周長和圓面積,其余3個靜態文本框分別用於對上述三個文本框進行文字說明。
■2個命令按鈕,“確定”和“退出”: 前者用於確定輸入值,計算圓周長和圓面積,然后把結果顯示在對應的輸出框上;后者用於結束程序的執行。
如下圖:

進行控件屬性設置(即鼠標選中控件右鍵單擊,點屬性):
1.主窗口:將標題值設置為“計算圓周長和圓面積”,其他默認。
2.編輯框:ID默認為:IDC_EDIT1。在“樣式”(Styles)選項卡中設置相關屬性值為:“靠左”(Left)。其余屬性采用默認值。
3.靜態文本框:
ID 標題 其他屬性
---------------------------------------------------------------------------------
IDC_STATIC1 輸入半徑 居中,垂直居中
IDC_STATIC2 圓周長 居中,垂直居中
IDC_STATIC3 圓面積 居中,垂直居中
IDC_STATIC4 默認 靠左,垂直居中,Client edge
IDC_STATIC5 默認 靠左,垂直居中,Client edge
4.按鈕:
ID 標題
---------------------------------------
IDC_BUTTON1 確定
IDC_BUTTON2 退出
現在便到了第三步,設計對象的事件驅動程序。
這里說點知識。對象的事件驅動程序在VC++中稱為消息處理成員函數。
在實際應用中,讀取或更新控件上的數據是對話框的非常重要的工作。MFC為此提供了一套標准方法:DDX(Data Exchange,數據交換)和DDV(Data Validation,數據校驗)技術。DDX通過成員變量(member variable)的方式實現對話框與控件之間的數據傳遞。如果要在對話框的消息處理函數中訪問控件上的數據,就必須先在對話框類(CCase1Dlg類)中分別為這些控件添加(聲明)一個成員變量,每一個成員變量綁定一個控件。在消息處理函數中是通過成員變量訪問控件的。
成員變量是對話框的public數據成員。有兩類成員變量:
■Value類成員變量:表示該變量的值為控件的數據。
■Control類成員變量:表示該成員變量就代表控件本身,即它是控件的一個對象,其值實際上就是控件的句柄。
句柄是什么?
Visual Studio系統給每個對象分配一個句柄(handle),它是一個4字節長的整數值,是對象的唯一內部編號。應用程序通過句柄訪問相應的對象。每個對象除了句柄外,還有一個對象標識符ID,可看作是對象的外部名。ID與句柄的區別主要在於:ID可以是用戶自行設定的;而句柄是系統內定的,對用戶是透明的,這能防止應用程序直接訪問對象的內部信息。
DDV用於數據的校驗,例如自動校驗字符串的長度和取值范圍。
使用MFC DDX/DDV的流程是:
①首先定義用於接收控件數據的成員變量。例如,為編輯框IDC_EDIT1定義一個Value類的double型的成員變量,用於接收用戶輸入的半徑值。定義變量的同時可以設定數據取值范圍,提供校驗。
②然后,在對應的消息處理成員函數中調用MFC函數傳遞數據。最簡單的相關MFC函數有:
UpdateData() //更新成員變量,將控件上的數據傳遞給成員變量
UpdateData(FALSE) //更新控件,將成員變量的值傳遞給控件
對於本實例,可設計如下成員變量和消息處理函數:
■為編輯框IDC_EDIT1定義一個double型的成員變量m_r,用於接收用戶在編輯框中輸入的半徑值;
■為靜態文本框IDC_STATIC4和IDC_STATIC5分別定義一個Cstring型成員變量m_girth和m_area用於向靜態文本框傳遞計算結果。靜態文本框只能處理Cstring(字符串)型數據。
注意:成員變量名的前綴“m_”是MFC的風格。MFC也有自己的數據類型,不過與C++很相似,容易理解。
■為“確定”按鈕建立一個“單擊”(BN_CLICKED)消息處理函數,用於計算圓周長和圓面積,並顯示計算結果。
■為“退出”按鈕建立一個“單擊”消息處理函數,用於結束程序的運行。
■建立一個對話框的初始化函數,對成員變量m_r、m_girth、m_area進行初始化。
操作步驟:
(1)添加成員變量
打開“MFC Class Wizard”(類向導)對話框。方法可以是:從VC6窗口的菜單欄上的“查看”菜單中選擇“建立類向導”選項,或者用鼠標右擊窗體,從彈出的快捷菜單中選擇“建立類向導”,或者按快捷鍵Ctrl+W。選擇“Member Variables”(成員變量)選項卡。從“Control IDs”(控件ID)列表框中,可以看到已經建立的各控件對象的ID。
為編輯框添加成員變量:選擇IDC_EDIT1,單擊右邊的“Add Variable…”(添加變量)按鈕,彈出“添加成員變量”對話框。
在第一個文本框(Member variable name)中輸入成員變量名,如m_r;在第二個下拉框(Category)中選擇成員變量的種類,Value;在第三個下拉框(Variable Type)中選擇成員變量的數據類型,double。單擊OK按鈕。回到“Member Variables”選項卡,設置變量m_r的取值范圍,如最小值為0,最大值為1000.0。用同樣的方法為靜態文本框IDC_STATIC4和IDC_STATIC5添加Cstring型成員變量m_girth和m_area,最大字符個數為10。
看下圖:

(2)編寫消息處理成員函數
①主窗口的初始化函數
切換到類向導的“Message Map”(消息映射)選項卡。在“Object IDs”(對象名)列表框中選擇主窗口的對象名CCase1Dlg;在“Messages”(消息)列表框中選擇消息WM_INITDIALOG;此時在“Member functions”(成員函數)列表框中會自動指出相應的MFC已定義的虛函數OnInitDialog(主窗口對象是由MFC默認生成的)。
單擊“Edit Code”(編輯代碼)按鈕,彈出Case1Dlg.cpp文件的編輯窗口,並顯示OnInitDialog()函數的代碼清單,找到注釋提示處:
// TODO: Add extra initialization here (在此下邊添加你初始化的代碼)
對於本實例,可添加如下代碼:
m_r =0.0; m_girth=m_area="0.000"; UpdateData(FALSE); //將數據傳給控件並顯示
即:
BOOL CCase1Dlg::OnInitDialog() { CDialog::OnInitDialog(); …………… // TODO: Add extra initialization here m_r =0.0; m_girth=m_area="0.000"; UpdateData(FALSE); //將數據傳給控件並顯示 return TRUE; // return TRUE unless you set the focus to a control }
②“確定”按鈕的消息處理函數
類似上述方法,在“Object IDs”列表框中選擇IDC_BUTTON1;在“Messages”列表框中選擇消息BN_CLICKED;單擊“Add Function”(添加函數)按鈕,此時在“Member functions”列表框中會出現一個新的函數名OnButton1,表示系統為該對話框生成了一個新成員函數(圖21);單擊“Edit Code”(編輯代碼)按鈕,彈出Case1Dlg.cpp文件的編輯窗口,並顯示OnButton1()函數的代碼清單,找到注釋提示處:
// TODO: Add your control notification handler code here (在此下邊添加控件消息的處理代碼)
對於本實例,可添加如下代碼:
UpdateData(); //將編輯框的數據傳遞給成員變量 double girth=2*3.1416*m_r; //計算圓周長 double area=3.1416*m_r*m_r; //計算圓面積 m_girth.Format(“%10.3f”,girth); //按格式寫入成員變量 m_area.Format("%10.3f",area); UpdateDtata(FALSE); //將數據傳給控件並顯示
注:函數Fornat()是CString類的成員函數,用來把數據轉換成CString類型的字符串。
③“退出”按鈕的消息處理函數
按上述方法,建立IDC_Button2的BN_CLICKED消息處理函數,並在注釋提示處輸入代碼:
void CCase1Dlg::OnButton2() { // TODO: Add your control notification handler code here EndDialog(1); //關閉對話框 }
下面進入最后一步,項目的編譯、鏈接和運行。

