我是荔園微風(fēng),作為一名在IT界整整25年的老兵,今天總結(jié)一下微軟MFC技術(shù)運(yùn)行機(jī)制。
很多初學(xué)者誤以為VC++開發(fā)必須使用MFC,其實(shí)不一定的。MFC的使用只能是提高程序在某些情況下的開發(fā)效率,而不能替代整個(gè)Win32程序設(shè)計(jì)。我認(rèn)為我們有必要再來(lái)好好講講MFC的本質(zhì)、MFC中的消息是以何種形式存在、懂得MFC中消息的存儲(chǔ)方式消息隊(duì)列、明白MFC程序運(yùn)行的原理消息響應(yīng)、MFC運(yùn)行流程。
我在上一篇關(guān)于MFC的文章中說(shuō)過(guò),MFC是微軟公司提供的類庫(kù),它以C++的形式封裝了Windows的接口函數(shù)API。類庫(kù)中包含大量的Windows句柄類、Windows控件類、Windows組件類。
直接使用Windows的API函數(shù)來(lái)開發(fā)產(chǎn)品,對(duì)于程序員來(lái)說(shuō)很困難。因?yàn)锳PI函數(shù)的數(shù)量十分多,而且名稱上有時(shí)很難看出來(lái)是什么意思。如果用win32開發(fā)一個(gè)窗口至少也得100多行的代碼,而一個(gè)軟件系統(tǒng)做出來(lái)后,那代碼量更是大的驚人。本質(zhì)上來(lái)說(shuō),MFC就是win32開發(fā)與Application framework的組合。這個(gè)組合為程序員創(chuàng)建了程序的一般框架模型,減少了應(yīng)用程序開發(fā)程序員的工作量。
為了方便大家理解MFC,現(xiàn)在我們做一個(gè)比喻。我們把MFC程序比喻為空調(diào)。
首先,威利斯·開利發(fā)明了世界上第一臺(tái)空調(diào),是下圖這個(gè)樣子的,于是空調(diào)的整個(gè)設(shè)計(jì)思想和原理被固定下來(lái),形成了第一代空調(diào),相當(dāng)于我們這里的Win32的Application framework。
而最新的空調(diào)就是在第一代空調(diào)的基礎(chǔ)上不斷迭代發(fā)展而來(lái)。現(xiàn)代空調(diào)是在第一代空調(diào)的基礎(chǔ)上不斷完善而來(lái),增加入不少新的技術(shù),這種增加的新技術(shù)類似于我們這里的各類Windows的接口函數(shù)API,然后對(duì)第一代空調(diào)的設(shè)計(jì)思想原理結(jié)合后來(lái)的新技術(shù)進(jìn)行了一次次的融合,而且更加模塊化組件化,形成了現(xiàn)代空調(diào)產(chǎn)品,也就是我們這里的MFC。如下圖這些工業(yè)用空調(diào)。
MFC的實(shí)質(zhì)就是對(duì)Win32程序的封裝,第一臺(tái)空調(diào)與后來(lái)各種技術(shù)的結(jié)合 就是現(xiàn)代空調(diào)發(fā)展的一個(gè)模板,Win32的Application framework與函數(shù)API的結(jié)合 就是MFC框架。
你如果想在現(xiàn)代空調(diào)上加入新技術(shù),就必須了解空調(diào)的原理。對(duì)于程序員來(lái)說(shuō),也必須了解MFC架構(gòu)。MFC程序的結(jié)構(gòu)一般是由一個(gè)CWinApp類對(duì)象和幾個(gè)從MFC派生的類組成。
我們以一個(gè)基于單文檔的MFC工程為例進(jìn)行講解,工程名為KongTiao。我們一建立KongTiao就會(huì)有如下圖幾個(gè)類,其中常用的是CMainFrame、CKongTiaoApp、CKongTiaoDoc、CKongTiaoView這4個(gè)類。
1.應(yīng)用程序類CKongTiaoApp
先在KongTiao.h通過(guò)下面代碼定議CKongTiaoApp類。
class CKongTiaoApp : public CWinApp //派生類:public 基類
{
public:
? ? ? CKongTiaoApp(); //構(gòu)造函數(shù),用于初始化
public:
? ? ? virtual BOOL InitInstance(); //實(shí)例化虛函數(shù)
? ? ? afx_msg void OnAppAbout(); //函數(shù)聲明
? ? ? DECLARE MESSAGE_MAP()
從第01行可看出它是從CWinApp類派生,它有且只有一個(gè)應(yīng)用程序?qū)ο螅?fù)責(zé)應(yīng)用程序的初始化、運(yùn)行和結(jié)束。
2.文檔類CKongTiaoDoc
先在KongTiaoDoc.h通過(guò)下面代碼定義CKongTiaoDoc類。
class CKongTiaoDoc : public CDocument //派生類:public基類
{
protected: //以下為保護(hù)成員函數(shù)
CKongTiaoDoc(); //構(gòu)造函數(shù),用于初始化
DECLARE DYNCREATE(CMessageDoc)
...
public:
virtual ~CKongTiaoDoc(); //析構(gòu)函數(shù)
...
};
從它的第01行可看出它是從CDocument類派生,用來(lái)管理數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的變化、存取。
3.視圖類CMessageView
同時(shí)文檔類還可以和視圖類合作,訪問(wèn)和更新數(shù)據(jù)。先在KongTiaoView.h通過(guò)下面代碼進(jìn)行定義,也就是CKongTiaoView視圖類的定義。
class CKongTiaoview : public CView //派生類:public基類
{
protected: //以下為保護(hù)成員函數(shù)
CKongTiaoView(); //構(gòu)造函數(shù),用于初始化
DECLARE DYNCREATE(CKongTiaoview)
...
public:
virtual void OnDraw(CDC* pDC); //畫視圖
virtual BOOL PreCreateWindow(CREATESTRUCT& cs); //創(chuàng)建窗口
...
public:
virtual ~CKongTiaoView(); //析構(gòu)函數(shù)
...
protected:
DECLARE MESSAGE MAP()
public:
afx msg void OnMouseMove(UINT nFlags, CPoint point); //鼠標(biāo)移動(dòng)的消息函數(shù)
};
從第01行可看出它是從CView類派生。視圖和文檔聯(lián)系在一起,在文檔和用戶之間起中介作用,即:在屏幕上顯示文檔的內(nèi)容,并把用戶輸入轉(zhuǎn)換成對(duì)文檔的操作。
4.主框架窗口類CMainFrame
代碼MainFrm.h是CMainFrame框類的定義。
?
class CMainFrame : public CFrameWnd? ?? //派生類:public基類
{
protected: //以下為保護(hù)成員函數(shù)
CMainFrame(); //構(gòu)造函數(shù),用于初始化
DECLARE DYNCREATE(CMainFrame)
...
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs); //創(chuàng)建窗口
public:
virtual ~CMainFrame(); //析構(gòu)函數(shù)
...
protected:
CStatusBar m_wndStatusBar; //聲明一個(gè)狀態(tài)欄對(duì)象
CToolBar m_wndToolBar; //聲明一個(gè)工具欄對(duì)象
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //用于創(chuàng)建窗口各種屬性
DECLARE_MESSAGE MAP()
};
從第01行可看出它是從CFrameWnd類派生,負(fù)責(zé)創(chuàng)建和控制菜單、工具欄、狀態(tài)欄等界面元素。
5.MFC類的底部派生關(guān)系
前面大家已經(jīng)看到很多類的派生關(guān)系,這4個(gè)默認(rèn)生成的類都是從CWinApp、CDocument 等類派生而來(lái),這就需要大家了解MFC類的底部派生關(guān)系,如圖所示。
第 1行的 CObject 類是大多數(shù) MFC 類的根類或基類。 CObject派生出CCmdTarget。類 CCmdTarget 是MFC類庫(kù)中消息映射體系的一個(gè)基類,是MFC處理命令消息的基礎(chǔ)核心。而CCmdTarget類又派生出了如圖中所示4種不同的類,即CWinThread、CDocTemplate、 CDocument、CWnd。
CWinThread:是MFC用來(lái)封裝線程的。每個(gè)MFC程序至少使用一個(gè) CWinThread派生類。而MFC程序員熟知的CWinApp應(yīng)用類就是從此處派生,這個(gè)派生關(guān)系可以從圖直觀看出。
CDocTemplate:是抽象的基類,它定義了文檔模板的基本函數(shù)功能。但它不能直接使用,通常應(yīng)用的是由其派生的兩個(gè)類。一個(gè)是CSingleDocTemplate,其用于SDI;另一個(gè)是MultiDocTemplate,其用于MDI。
CDocument:它為用戶定義的文檔類提供了基本的函數(shù)功能。
CWnd:是 MFC 窗口類的基類,提供了微軟基礎(chǔ)類庫(kù)中所有窗口類的基本功能,它是MFC學(xué)習(xí)的重中之重。由它派生出了3個(gè)類:CFrameWnd、CView、CControlBar。其中前兩個(gè)類就是讀者的學(xué)習(xí)重點(diǎn)。
注意:CDocTemplate類對(duì)于大家來(lái)說(shuō),可以暫且不去關(guān)注它。在大家的學(xué)習(xí)范圍中,很少涉及到此類。
提到MFC,不能不說(shuō)應(yīng)用程序框架,提到框架,又不能不說(shuō)視圖和文檔。下面再詳細(xì)介紹下這兩個(gè)類:CFrameWnd(負(fù)責(zé)主窗口)和CView(負(fù)責(zé)視圖)。
CFrameWnd:往往用于創(chuàng)建應(yīng)用程序的主窗口,它能很好地支持系統(tǒng)菜單和控制條。CFrameWnd直接支持單文檔界面(SDI),對(duì)于多文檔界面(MDI),則使用其派生類CMDIFrameWnd和CMDIChildWnd。
CView:是MFC程序設(shè)計(jì)中使用率最高的窗口對(duì)象,它是用戶的主要操作界面。因?yàn)樗ǔR阅撤N形式表示文檔數(shù)據(jù),所以稱之為視圖。一個(gè)視圖對(duì)象只關(guān)聯(lián)一個(gè)文檔對(duì)象,而一個(gè)文檔對(duì)象可以關(guān)聯(lián)多個(gè)視圖,每個(gè)視圖對(duì)象以不同形式表示文檔數(shù)據(jù)。
為了更直觀地了解MFC程序的文件構(gòu)成,新建一個(gè)MFC單文檔工程,命名為Message。此工程一經(jīng)建立就會(huì)自動(dòng)生成許多頭文件和源文件,如圖所示。
?自動(dòng)生成的這些文件的名字及對(duì)應(yīng)文件的用途通過(guò)兩個(gè)表格來(lái)說(shuō)明。如下表是AppWizard所生成的頭文件。
下表是AppWizard所生成的源文件。
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-479166.html
作者簡(jiǎn)介:荔園微風(fēng),1981年生,高級(jí)工程師,浙大工學(xué)碩士,軟件工程項(xiàng)目主管,做過(guò)程序員、軟件設(shè)計(jì)師、系統(tǒng)架構(gòu)師,早期的Windows程序員,Visual Studio忠實(shí)用戶,C/C++使用者,是一位在計(jì)算機(jī)界學(xué)習(xí)、拼搏、奮斗了25年的老將,經(jīng)歷了UNIX時(shí)代、桌面WIN32時(shí)代、Web應(yīng)用時(shí)代、云計(jì)算時(shí)代、手機(jī)安卓時(shí)代、大數(shù)據(jù)時(shí)代、ICT時(shí)代、AI深度學(xué)習(xí)時(shí)代、智能機(jī)器時(shí)代,我不知道未來(lái)還會(huì)有什么時(shí)代,只記得這一路走來(lái),充滿著艱辛與收獲,愿同大家一起走下去,充滿希望的走下去。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-479166.html
到了這里,關(guān)于微軟MFC技術(shù)運(yùn)行機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!