MFC實現原理剖析

“現在已經是人工智能、大數據的時代,雲+端纔是王道,桌面程序設計已經過時了,還有沒有必要學習MFC?”
這是許多困擾剛剛入行朋友的問題,不可否認,由於python、Java等開發語言和環境的流行,Visual C++的應用範圍也相應縮小。
“有人說現在c++越來越接近邊緣性語言?c++程序員以後的發展方向在那裏,我學習MFC會不會被淘汰?”
的確C++作爲普及性應用程序設計語言的地位已經不再,但是它作爲系統程序設計語言的地位沒變。 筆者個人的淺見在於:一個系統程序員的核心優勢之一就是對計算機裝置的透徹理解。在筆者求學階段,筆者的導師曾經有過這樣的指導,對於本人的影響非常深刻:
“你們覺得你們學計算機這個專業最大的優勢是什麼?是會編程序嗎?會寫算法嗎?”
“論寫算法,你們不如數學方向的同學,他們天天接受邏輯思維訓練,抽象能力的培養,你們不佔優勢”
“論寫業務邏輯,比如信息管理系統,你們不如有行業經驗的懂開發技術的人員,因爲你們在業務理解上不佔優勢”
“寫操作硬件,你們不如寫自動化,機電一體化的,不如通信的,他們理解協議,用代碼指揮硬件的能力比你們也要強”
“那麼,計算機專業的核心優勢在哪裏?”
“我認爲一定是在你們對整個計算機裝置的理解,這個纔是你們要強化的技能核心”
正是因爲此,筆者纔對進入行業領域的C++學習者不斷建議:從各種角度提升自己的對計算機裝置的核心理解。
那麼理解計算機裝置的一種可選路徑在哪裏呢?筆者認爲莫過於對操作系統的學習和探索。毫無疑問,當前在PC市場中最爲人們所熟知的操作系統就是windows了。對於普通用戶來說,當他雙擊word圖標,啓動word,開始打字,排版,插入圖片的時候,他一定認爲是自己在處理辦公業務。當這個用戶按下鍵盤a,打出一個字母,按下鼠標,圈出一段文字,他一定認爲是自己“在寫,在畫”這個內容。但是作爲一名開發人員來說,你又是如何理解這種行爲呢?
實際上,真正在寫,在畫的並不是這位用戶,而是word這個程序。從運行原理來說,恐怕這樣的描述更加精準。
MFC實現原理剖析
其實,這個呈現出來的過程中word與windows操作系統交互被用戶從邏輯上忽略了。而我們程序開發人員的任務實際上是在兩端編程
一方面,我們接受用戶的輸入,讓操作系統感知到我們應用程序的存在,並將其做相應的處理邏輯;
另一方面,我們將處理好的邏輯通過windows操作系統的幫助以友好的方式呈現給用戶。
這兩個方面都涉及到編寫代碼的工作,這纔是我們編碼的邏輯所在。
接下來的問題就是,windows感知到用戶的輸入好理解,那麼如何理解windows感知到應用程序的存在呢?還是以word爲例
MFC實現原理剖析
打個比方,就像一所學校,每一個學員都有一個代號供學校管理調度,要求你聽課,考試。有了hwnd這個概念,我們就知道了,同樣,windows操作系統需要顯示,銷燬這個窗體,都需要通過hwnd來操作。我們編程的時候,就可以把自己需要操作的hwnd給windows操作系統,讓windows操作系統實現我們的目的。很顯然,一個hwnd是一個窗口的表示,同樣的,呈現一個窗口肯定需要一套複雜的結構,就好比一個在學校的學生,有學號,有出生年年月,有性別,有專業,各種各樣的分量信息。一個窗口結構,肯定也是一個複雜的分量組合。對應到語言層面,一定是一個C語言的struct的結構。
C語言是開發操作系統的核心語言,很顯然,Windows API是面向C語言風格的。大家都知道C++是C語言的超集,微軟爲了方便當時的開發人員將已經存在的C語言開發方式,封裝成了一套類庫,這個就是MFC的由來,我們可以認爲MFC是Windows C++的API。於是,這個就帶來了一個新的問題:如何用C++的語義來替代C風格的開發方式。
最直接的方式就是建立面向對象的語義到實際開發概念的映射,實質今日,許多老的軟件需要維護的工作,依然會從msdn中查找mfc的類結構,其中最重要的一個結構就是CWnd,這個又稱爲窗口類,我們來看下微軟是怎麼做的。
class CWnd :public CCmdTarget {
DELCARE_DYNCREATE(CWnd)
public:
CWnd();
virtual ~CWnd();

HWND m_hWnd;
operator HWND() const { return m_hWnd; }
HWND GetSafeHwnd() { return this == NULL ? NULL : m_hWnd; }

//窗口句柄映射
static CWnd* FromeHandle(HWND hWnd);
static CWnd* FormHandlePermanet(HWND hWnd);
BOOL Attach(HWND hWndNew);
HWND Detach();

…}
在C++的語義看來,用來交互的一定是一系列的對象,這些對象與對象之間的交互運動完成軟件的工作過程。比如我們做這樣一個想象,圖示中是內存中已經存在的一系列對象,這些對象之間相互調用,只要合理安排好這些調用的先後秩序,同時這些對象的數據進行加工處理,得到結果就是這個軟件系統運行過程。
MFC實現原理剖析

藉助這樣的思想,微軟在改造C語言的編程風格的時候,他就要考慮概念的轉移,以前,程序原只需要操作hwnd就可以直接和操作系統交互,現在則不然,首先,要刻畫一個c++的觀念與hwnd對應。這個觀念的就是CWnd類設計的初衷。CWnd是批量製造窗體對象的類。他可以批量的new 出一堆窗體對象來。
首先,CWnd對象就必須有Hwnd,這個就是
MFC實現原理剖析
設計的由來。
那麼,這些函數又是什麼設計語義呢?
MFC實現原理剖析
這個就要談MFC的體系了。
我們首先看下擁有了mfc之後,應用程序與操作系統的交互發生了什麼樣的變化:
MFC實現原理剖析
在沒有MFC的時候,所有的應用程序的消息都是直接和windows系統打交道。而MFC應用程序則不然,它像一個楔子一樣加載了應用程序與操作系統之間。如果我們寫一個mfc的word,所有的windows消息的截獲和感知,都是通過mfc來完成的。這就好像以前你可以直接和老闆對話,而現在你的所有的請求和應答都只能委託給mfc來操作。
有了這個概念,再理解上面的代碼就順暢了。以前我們自己的應用程序要提請windows操作系統操作,直接訪問hwnd就可以了。但是現在我們按照c++語法,我們用的是Cwnd對象。這個CWnd是一個C++對象,而且是MFC創造出來的c++對象,並不是windows的對象。所以,MFC有責任管理好這個對象,這個對象的出生與消亡都跟隨的是C++語義。因此,當我們需要一個表達一個窗體的概念的時候,我們很自然的就會new一個Cwnd的對象出來。但是,這個CWnd對象是有風險的——如果這個CWnd對象先於windows的窗體出現怎麼辦?(CWnd對象的內存已經構建好了,但是hwnd還爲空,所以它的m_hWnd爲空)。同樣的CWnd對象概念的出現將windows窗體的hWnd概念和CWnd的概念進行了剝離,那麼從理論上講CWnd對象可以結合任意的hWnd對象。(只要將m_hWnd賦予不同的值就可以了)。
這又是MFC的一個高超之處,就是要將hWnd和CWnd進行觀念解耦,當應用程序需要用CWnd對象的觀念表達Windows窗體的時候,用參數傳入就可以了。以BOOL Attach(HWND hWndNew);爲例,程序開發人員大可以將一個已經存在的windows窗體的hwnd傳給當前的CWnd對象,通過attch方法,靈活的將windows窗體附着在Cwnd這個C++對象上。這種設計技巧是十分精妙的,既可以在不變更已有系統的情況下,靈活的用C++的方法進行開發。

http://edu.51cto.com/sd/18816
MFC實現原理剖析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章