?
了解如何使用
windows API
函數(shù)編程后,對(duì)
windows
應(yīng)用程序的大體結(jié)構(gòu)框架有初步的認(rèn)識(shí)。但是直接使用
windows API
進(jìn)行編程程序員需要自己編寫大量代碼。像我這種從一開始接觸程序開發(fā)就是學(xué)習(xí)的
OO
的人來說,實(shí)在是無法忍受。從現(xiàn)在開始,我把重點(diǎn)轉(zhuǎn)到
VC++
的另一方面,利用
MFC
進(jìn)行和向?qū)砭帉?/span>
windows
程序。
MFC
(
Microsoft Foundation Class
)
是用來編寫
windows
應(yīng)用程序的
C++
類集,它封裝了大量的
windows API
函數(shù)和
windows
控件,并且以層次結(jié)構(gòu)組織起來。使程序員在開發(fā)時(shí)能方便的進(jìn)行代碼重用,加快開發(fā)速度并提高代碼的可靠性。
應(yīng)該注意的是
MFC
是 使用C++語言實(shí)現(xiàn)的一個(gè)類庫,但并非是進(jìn)行GUI程序設(shè)計(jì)的唯一標(biāo)準(zhǔn)。
?
有
OO
基礎(chǔ)或者是學(xué)習(xí)過
JAVA
語言理解
MFC
的體系結(jié)構(gòu)會(huì)比較輕松。目前,
MFC
中包含了大約
100
多個(gè)類,通過定義類對(duì)象并調(diào)用對(duì)象的成員函數(shù)來實(shí)現(xiàn)相應(yīng)的功能。
?
下面簡(jiǎn)要介紹一下
MFC
的類組織結(jié)構(gòu):
1.????????
根類
CObject
MFC
中絕大多數(shù)類和自定義子類的根類,它提供了許多編程所需要的公共操作如:對(duì)象建立和刪除、串行化支持、對(duì)象診斷、運(yùn)行時(shí)信息以及集合類的兼容等
?
2.????????
命令相關(guān)類
CCmdTarget
它是
CObject
的直接子類,它是
MFC
中具有消息映射屬性的基類。一般很少需要程序員直接從
CcmdTarget
直接派生新類。
?
3.????????
線程基類
CWinThread
所有線程的基類,可以直接使用,它封裝了操作系統(tǒng)的線程化功能。
?
4.????????
窗口應(yīng)用程序類
CWinApp
每個(gè)應(yīng)用程序有且只有一個(gè)應(yīng)用程序?qū)ο螅谶\(yùn)行程序中該對(duì)象與其它對(duì)象相互協(xié)調(diào),該對(duì)象從
CwinApp
類中派生而來。它封裝了初始化,運(yùn)行,終止應(yīng)用程序的代碼。
?
5.????????
文檔
/
視類
CDocument/CView
文檔對(duì)象由文檔模板對(duì)象創(chuàng)建,管理應(yīng)用程序的數(shù)據(jù)。
CDocument
支持標(biāo)準(zhǔn)的文檔操作,這些操作包括文檔創(chuàng)建、下載、保存等。一個(gè)應(yīng)用程序可以操作多種文檔類型,每一種文檔類型都有特定的文檔模板(
document template
)。
用戶通過文檔和相關(guān)聯(lián)的視圖對(duì)象(
CView object
)與文檔進(jìn)行交互。一個(gè)視圖顯示文檔中的信息,并把用戶在框架窗口內(nèi)的操作轉(zhuǎn)換成對(duì)文檔操作的相應(yīng)命令。當(dāng)用戶打開一個(gè)文檔時(shí),應(yīng)用程序?qū)嶋H上創(chuàng)建了一個(gè)視圖并把這個(gè)視圖和相應(yīng)的文檔聯(lián)系在一起。一個(gè)視圖充當(dāng)了溝通用戶和文檔對(duì)象的中間橋梁的作用。
?
6.????????
可視對(duì)象類
CWnd
該類提供了
MFC
中所有窗口類的基本功能,它的消息映射機(jī)制隱藏了窗口函數(shù)
WndProc
。一個(gè)
windows
消息通過消息映射發(fā)送到相應(yīng)的
CWnd
類的
OnMessage
成員函數(shù),通過重載
OnMessage
函數(shù)來對(duì)特定的消息進(jìn)行處理。
CWnd
類有許多經(jīng)常使用的子類,如
CMenu
類,
CDialog
類,
CButton
類等等。
?
7.????????
通用類
通用類提供了許多共用服務(wù),例如文件
I/O
(
CFile
類和
CArchive
類)、異常處理(
CException
類)等。
?
8.????????
OLE
類
OLE1.0
規(guī)范是
MS
在
1991
年發(fā)布的。它是處理復(fù)合文檔的一種方法:
Object Linking and Embedding
技術(shù)。所謂復(fù)合文檔,就是在一個(gè)文檔中同時(shí)保存了如文本、圖像和聲音等多種不同類型的數(shù)據(jù),而這些數(shù)據(jù)又可以通過不同的應(yīng)用程序用不同的格式產(chǎn)生。
1993
年發(fā)布的
OLE2.0
是基本對(duì)象的一整套體系結(jié)構(gòu),能夠擴(kuò)展、定制和增強(qiáng)服務(wù)功能,它的理論基礎(chǔ)是
COM
技術(shù)。
此外,
ActiveX
也是一種對(duì)
OLE
技術(shù)的擴(kuò)展,它使
OLE
進(jìn)入
Internet
和
Intranet
。
?
9.????????
ODBC
類
為了支持帶有
ODBC
驅(qū)動(dòng)程序的各種數(shù)據(jù)庫管理系統(tǒng),
MFC
也提供了
Cdatabase
和
CRecordset
類,用于管理數(shù)據(jù)庫的連接及其操作。
?
10.????
MFC
中全局函數(shù)和變量
在
MFC
中提供的全局函數(shù)和變量一般都以
Afx
開頭,它們可以在
MFC
應(yīng)用程序的任務(wù)地方中使用,如:
AfxAbort
、
AfxMessageBox
等等。
?
在使用
VC
生成
MFC
應(yīng)用程序時(shí),
IDE
會(huì)自動(dòng)生成許多代碼,以一個(gè)簡(jiǎn)單的對(duì)話框程序?yàn)槔瑢?huì)有如下幾個(gè)主要的文件:
stdafx.h/cpp ???????????????
標(biāo)準(zhǔn)系統(tǒng)包含文件,或是常使用但不常更改的
MFCles1.h/.cpp???????????
應(yīng)用程序類
MFCles1Dlg.h/cpp???????
對(duì)話框類
Resource.h??????????????????
資源頭文件,被
MFCles1.rc
所使用
?
???????????
MFC
應(yīng)用程序的一般結(jié)構(gòu)
就設(shè)計(jì)模式來看,
MFC
應(yīng)用程序是一個(gè)標(biāo)準(zhǔn)的單例模式。每一個(gè)應(yīng)用程序有且僅有一個(gè)實(shí)例對(duì)象:
theApp
程序執(zhí)行的基本流程,就我現(xiàn)在的理解而言:
首先應(yīng)該從在應(yīng)用程序體系結(jié)構(gòu)類中聲明的一個(gè)全局實(shí)例對(duì)象
theApp
入手(C++里的全局類對(duì)象初始化在main函數(shù)之前),在進(jìn)入CWinApp類的構(gòu)造函數(shù)之后,程序才進(jìn)入原來Windows API里的那個(gè)入口函數(shù):AfxWinMain。
我們?cè)趯慚FC程序時(shí)并沒有顯示的指出WinMain入口函數(shù)的位置。這個(gè)函數(shù)的定義被安置在了APPMODUL.CPP文件里(這一文件位于VS安裝目錄下的VC98目錄里的MFC源文件里)。每個(gè)app實(shí)例被構(gòu)造后,會(huì)產(chǎn)調(diào)用相應(yīng)的InitInstance函數(shù)進(jìn)行初始化。原來的注冊(cè)窗口類的工作被放在了WINCORE.CPP文件里的AfxEndDeferRegisterClass函數(shù),這里MFC已經(jīng)為我們定義好了幾種默認(rèn)的窗口類。然后就會(huì)調(diào)用CPreCreateWnd函數(shù)進(jìn)行窗口的顯示工作。最后,使用CWinThread::Run方法啟動(dòng)消息循環(huán),至此,整個(gè)窗口應(yīng)用程序就運(yùn)行起來了。windows應(yīng)用程序可以被同時(shí)多次運(yùn)行,第一次運(yùn)行完成初始化工作后,以后每次運(yùn)行程序拷貝都全調(diào)用InitInstance函數(shù)進(jìn)行初始化工作。
class CMFCles1App : public CWinApp
{
public:
?????? CMFCles1App();
//
重寫一些父類方法
?????? public:
?????? virtual BOOL InitInstance();
//
實(shí)現(xiàn)消息映射的宏
?????? DECLARE_MESSAGE_MAP()
};
?
extern CMFCles1App theApp;//
代碼應(yīng)用程序本身
?
以一個(gè)簡(jiǎn)單的對(duì)話框程序?yàn)槔?span lang="EN-US">InitInstance函數(shù)里完成了以下工作
CMFCles1Dlg dlg;
??? m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
第一行聲明了一個(gè)對(duì)話框類對(duì)象,第二行將其賦值給當(dāng)前應(yīng)用程序類的成員變量,這是一個(gè)指向主窗口的指針,最后一行顯示窗口。
?
了解了一點(diǎn)關(guān)于應(yīng)用程序類的知識(shí)后,再來分析剩下的與GUI有關(guān)的另一個(gè)類,這里使用一個(gè)對(duì)話框類作一點(diǎn)說明。
同樣,
MFCles1Dlg
則派生自
CDialog
類
class CMFCles1Dlg : public CDialog
{
public:
?????? CMFCles1Dlg(CWnd* pParent = NULL);??? //
標(biāo)準(zhǔn)構(gòu)造函數(shù)
?
protected:
?????? HICON m_hIcon;//
應(yīng)用程序圖標(biāo)的句柄
DECLARE_MESSAGE_MAP()
?
?????? //
生成的消息映射函數(shù)
?????? virtual BOOL OnInitDialog();
?????? afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
?????? afx_msg void OnPaint();
?????? afx_msg HCURSOR OnQueryDragIcon();
};
DECLARE_MESSAGE_MAP()
是一個(gè)用來定義消息映射的宏,而下面以
afx_msg
開頭的函數(shù)都是消息的響應(yīng)函數(shù),這比起
API
里面把消息都寫在一些
switch
語句中要更清楚,也方便了修改。要實(shí)現(xiàn)對(duì)話框?qū)ο⒌捻憫?yīng)還需要在類中加上這兩行
?
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
所有的消息映射函數(shù)都要寫在這兩行之間,例如ON_WM_RBUTTONDOWN( )就定義了一個(gè)右鍵按下的消息映射。MFC已經(jīng)有了預(yù)定義好了許多消息映射函數(shù)的格式,需要查看可以參考MSDN。