?? c-c++ mfc.htm
字號:
</P>
<P
align=justify> CFrameWnd:Create在函數中調用CreateEx(CWnd有這個成員函數,但其派生類CFrameWnd并沒有,所以這里調用的實際上是CWnd:CreateEx);后者又調用PreCreateWindow虛擬函數(它在CWnd及其派生類CFrameWnd都有定義,所以實際上調用的是CFrameWnd::PreCreateWindow),這個函數調用了AfxDeferRegisterClass宏,它表示如果變量afxRegisteredClass的值顯示系統已經注冊了fClass
這種窗口類,MFC啥也不做,否則就調用AfxEndDeferRegisterClass(fClass){它調用兩個函數完成實際的窗口類注冊操作,一個是RegisterWithIcon,一個是AfxRegisterClass},準備注冊之。
</P>
<P align=justify> 窗口顯示與更新;
CMyFrameWnd::CMyFrameWnd結束后,窗口已經誕生出來;程序又回到CMyWinApp::InitInstance,于是調用ShowWindow函數令窗口顯示出來,并調用UpdateWindow函數令Hello程序送出WM-PAINT
</P>
<P align=justify>CWinApp::Run----程序生命的活水源頭 </P>
<P
align=justify>Run又是CWinApp的一個虛擬函數,我們沒有改寫它(大部分情況下也不需要改它),所以上述操作相當于調用CWinApp::Run
</P>
<P align=justify>WinMain已由MFC提供,窗口類已由MFC注冊完成,連窗口函數也都由MFC提供 </P>
<P align=justify>把消息與處理函數連接在一起:Message Map機制 </P>
<P
align=justify>MFC提供給應用程序使用的“很方便的接口”是兩組宏,以Hello為例,第一個操作是在Hello.h的CMyFrameWnd加上DECLARE-MESSAGE-MAP;第二個操作是在Hello.cpp的任何位置(當然不能在函數內)使用宏
</P>
<P align=justify>BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) </P>
<P align=justify>ON_COMMAND(IDM_ABOUT, OnAbout) </P>
<P align=justify>ON_WM_PAINT() </P>
<P align=justify>END_MESSAGE_MAP() </P>
<P align=justify>來龍去脈總整理 </P>
<P align=justify>程序的誕生 </P>
<P align=justify>Application object 產生, 內存于是獲得配置,初值亦設立了。 </P>
<P align=justify>AfxWinMain執行AfxWinInit,后者又調有AfxInitThread,把消息隊列盡量加大到96
</P>
<P align=justify>AfxWinMain執行InitApplication。這是CWinApp的虛擬函數,我們通常不改寫它 </P>
<P align=justify>AfxWinMain執行InitInstance。這是CWinApp的虛擬函數,我們必須改寫它 </P>
<P align=justify>CMyWinApp::InitInstance “new”了一個CMyFrameWnd對象 </P>
<P
align=justify>CmyFrameWnd構造函數調用Create,產生主窗口。我們在Create參數中指定的窗口類是NULL,于是MFC根據窗口種類,自行為我們注冊一個名為“AfxFrameOrView42d”的窗口類。
</P>
<P align=justify>回到InitInstance中繼續執行ShowWindow,顯示窗口 </P>
<P align=justify>執行UpdateWindow,于是發出WM-PAINT </P>
<P align=justify>回到AfxWinMain,執行Run,進入消息循環。 </P>
<P align=justify>程序開始運行: </P>
<P align=justify>程序獲得WM-PAINT消息(由CWinApp::Run中的::GetMessage循環) </P>
<P align=justify>WM-PAINT經由::DispatchMessage送到窗口函數CWnd::DefWindowProc中。
</P>
<P align=justify>CWnd::DefWindowProc將消息傳遞到消息映射表格 </P>
<P
align=justify>傳遞過程中發現有相符項目,于是調用項目中對應的函數。此函數是利用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之間的宏設立起來的。
</P>
<P align=justify>標準消息的處理程序亦有標準命名,例如WM-PAINT必由OnPaint處理 </P>
<P align=justify>程序的死亡: </P>
<P align=justify>使用者單擊File/Close,于是發出WM-CLOSE </P>
<P align=justify>CMyFrameWnd并沒有設置WM-CLOSE處理程序,于是交給默認的處理程序 </P>
<P align=justify>默認函數對于WM-CLOSE的處理方式是調用::DestroyWindow,并因而發出WM-DESTROY
</P>
<P align=justify>默認的WM-DESTROY處理方式是調用::PostQuitMessage,因此發出WM-QUIT </P>
<P
align=justify>CWinApp::Run收到WM-QUIT后會結束內部之消息循環,然后調用ExitInstance,這是CWinApp的一個虛擬函數;如果CMyWinApp改寫了ExitInstance,那么CWinApp::Run所調用的就是CMyWinApp::ExitInstance,否則就是CWinApp::ExitInstance
</P>
<P
align=justify>最后回到AfxWinMain,執行AfxWinTerm,結束程序</P></TD></TR></TBODY></TABLE><BR>
<TABLE height=6835 cellSpacing=1 cellPadding=1 width=758 align=center
bgColor=#000000 border=0>
<TBODY>
<TR bgColor=#5f7189>
<TD background="C-C++ MFC.files/bg_bar.gif" bgColor=#ffffff
height=24><FONT color=#000000><STRONG>應用MFC開發高級應用程序<FONT size=4><A id=VC4
name=VC4></A></FONT></STRONG><FONT
color=#000000>(文章來源:龔建偉老師的技術主頁http://www.gjwtech.com)</FONT></FONT></TD></TR>
<TR bgColor=#5f7189>
<TD width="22%" bgColor=#ffffff height=6812><FONT
color=#000000><STRONG>目次</STRONG>:<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC41">一、使用C/C++及VC與VB之比較</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC42">二、MFC編程綜述</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC42">三、使用單文檔-多視結構</A>
</FONT><FONT color=#000000><A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC44">四、使用DDE服務</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC45">五、使用3D控制</A>
<A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC46">六、使用自定義消息</A> </FONT><FONT
color=#000000><A
href="http://skygray.ee.tokushima-u.ac.jp/~wangfei/research/vc/vc-1.html#VC47">七、使用不帶文擋-視結構的MFC應用</A>
<A
href="http://www.gjwtech.com/vcandc/vc3cvbcompare.htm#%B0%CB%A1%A2MFC%D3%A6%D3%C3%B5%C4%C8%CB%B9%A4%D3%C5%BB%AF">八、MFC應用的人工優化</A></FONT>
<P align=left><FONT
color=#000000><BR><STRONG>[摘要]</STRONG>:目前在Windows下開發應用程序的工具雖然很多,但是C/C++作為一種非常成熟和高效的開發語言在大型復雜項目的開發中仍然得到了廣泛應用。為了減輕程序開發負擔,提高開發效率,各種流行的C++都提供了類庫,本文就是針對如何在Visual
C++環境中使用MFC類庫來開發高級程序所需要解決的一些問題進行了的探討,重點討論了利用MFC開發單文檔多視應用程序和DDE應用程序的方法。</FONT></P>
<P align=left><FONT color=#000000><A id=VC41
name=VC41><B>一、使用C/C++</B></A></FONT></P>
<P align=left><FONT
color=#000000> 隨著Windows系列操作系統的日益普遍,傳統的基于DOS編程逐漸轉向Windows下編程已經成為必然趨勢。目前在Windows下開發應用程序的工具很多,典型的如Borland
C++、Visual C++、Visual
Baisic以及Delphi等等。每種開發工具都各有其特點,一般來講用戶可以根據自己的使用習慣和開發項目的性質來選擇具體的開發語言。</FONT></P>
<P align=left><FONT color=#000000> Visual
Basic是一個被軟件界稱之為劃時代的革新產品,該軟件改變了人們開發Windows程序的方式,它采用交互式的可視化操作,使得人們開發Windows程序的每一過程都有直觀形象的反饋,從而加速整個開發進程。Visual
Basic使得Windows程序設計人員不再只依賴于復雜的SDK編程,使得開發Windows程序非常容易,可以說,用戶學習并使用VB來開發Windows應用的時間是最短的。Visual
Basic版本幾經演變,目前已經發展到5.0。在4.0版本中,由于完全使用了面向對象的編程概念,同時具有Windows 3.1和Windows
95下的版本,因而使得其開發復雜程序的功能逐漸增強。VB5.0則拋棄了Windows
3.x的用戶,只能在32位Windows中使用,據悉,該版本吸收了Delphi的成功策略,引入了本地代碼(Native
Code)編譯器,從而使得程序執行速度大大加快,克服了以往版本由于執行文件采用P-Code代碼而導致運行速度慢的特點,根據微軟的聲明,該版本的采用本地代碼編譯后得到的應用程序在某些情況下執行速度較以往提高了10~20倍,執行速度可以直逼與采用Visual
C++編寫的應用,而應用開發速度則是VB的強項,因此Visual Basic 5.0非常具有競爭性。目前Visual
Basic非常廣泛地用于開發各種Windows程序,如數據庫前端應用程序和多媒體應用等。但是,在作者看來,采用VB也有一定的缺點,原因有以下幾點:</FONT></P>
<P align=left><FONT color=#000000>1. Visual
Basic來源于Basic語言,雖然經過微軟的不斷增強,但是仍然缺乏非常靈活的數據類型和編程策略,因而在開發一些項目必須的復雜數據結構遇到麻煩,如鏈表、圖和二叉樹等等。由于在中大型項目開發后期,開發工作不再以界面為主,而是在算法設計和底層軟硬件工作,這就使VB開發項目的后期工作量大幅度增加,為了達到項目要求,經常需要再轉向C/C++開發一些專用的動態連接庫來解決問題。</FONT></P>
<P align=left><FONT color=#000000>2. Visual
Basic運行速度慢,前文講過,采用P-Code代碼雖然執行文件很小,但是在運行時需要解釋執行,并且,它的運行必須有對應的VBRUN.DLL和所使用的VBX或者OCX支持。對于浮點操作密集或者循環嵌套很多的應用來說,VB沒有采取特別的優化,因而執行速度遠不如用C/C++和Fortran開發的應用速度快。VB
5.0雖然通過引入本地代碼編譯器大大彌補了這個缺陷,但是由于其只能運行于32位Windows環境因<BR>而在16位Windows上速度問題仍然得不到解決。雖然目前轉向32位Windows的趨勢非常強勁,但是不容忽視由于硬件的限制或者使用習慣等諸多原因,還有許多用戶仍然在16位Windows上工作。在計算機十分普及的美國,96年使用16位Windows的用戶仍然超過了使用32位Windows的用戶,任何進行系統軟件設計的人員都應該照顧到這些仍然使用16位Windows的用戶。</FONT></P>
<P align=left><FONT color=#000000>3.
VB不能靈活地使用系統資源。熟悉Windows編程的人都知道,如果要直接訪問硬件或者要編寫對系統進行有效訪問的應用程序,沒有Windows
API函數的幫助則非常困難,但是令VB程序員失望的是,API函數是用C語言和匯編語言實現的,是為C編程準備的,如果要在VB里面使用這些上千個API函數則比較麻煩,特別是,如果設計人員不懂C語言則尤其困難。由于API函數的復雜性,而其本身不是為了方便VB編程而提供的,因此在VB里面調用API函數需要一定的技巧,這些技巧足夠用一本很厚的書來表述。VB程序員可以從書店里找到好多本類似的書籍。可以說,任何一個VB程序員發展到一定階段都需要與眾多的API函數打交道。另外,由于VB不支持端口操作,因此,如果要編寫類似數據采集等需要與硬件交互的程序則需要求救于C/C++語言。<BR><BR>4.
Visual
Basic項目分發和管理困難,其原因同上講的,VB應用的運行不能脫離VB的運行庫和所使用的控件,因此,如果開發人員要將VB應用分發給用戶那么一定要帶上VB的運行庫和所使用的控件,并且要保證正確安裝,這就導致即使一個非常簡單的應用也需要附帶大量其它相關支撐庫程序,對于VB
4.0及更高版本,由于大量的使用了OLE控件(在VB中稱為OCX),其安裝更為復雜。</FONT></P>
<P align=left><FONT
color=#000000> Delphi軟件是國際寶蘭公司(Borland)的得意之作,也是備受軟件界推崇,與VB一樣,它完全是一個交互式的可視化開發平臺,支持Client/Server應用程序的開發,其最新版本2.0可以開發Windows
3.x、Windows 95和Windows
NT的應用程序。Delphi開發速度也非常快,與VB相比,由于具有本地代碼編譯器因此它產生的可執行文件執行速度大大加快。Delphi軟件是一個非常有競爭力的軟件,采用的是面向對象的Object
pascal語言,支持硬件操作和API調用。但是由于采用的編程語言為Pascal,這種語言并不非常流行,許多程序設計人員完全不熟悉這種語言,因此極大地限制了該軟件的使用,如果寶蘭公司能夠將Delphi軟件提供的RAD開發機制引入到其Borland
C++中,則可能會形成一個非常成功的產品(目前該版本已經推出,即C++ Builder,筆者注)。</FONT></P>
<P align=left><FONT
color=#000000> VB和Delphi引入的可視化開發方法還有一個共同的缺點就是各個版本之間的兼容問題。一般來講,采用這些可視化開發工具開發的應用程序在移植到高版本時不會遇到太大困難,但是一旦往相反方向移植則困難重重,有時甚至不可能。C/C++語言則不具有這種局限性,各個版本之間的相互移植并不困難,高版本往低版本移植一般只需重建工程文件即可大功告成。綜上所述,根據作者的觀點,如果要開發一個大型復雜的應用程序首選的還是C/C++,特別是在16位Windows下。雖然這會使前期工作增加,但是在項目的中后期將逐漸會領略到其優越性和開發效率,其靈活高效的執行代碼適合于對速度和應用程序之間的協同性要求很高的場合。純粹基于Windows
SDK來開發Windows程序是一項艱巨的工程,值得慶幸的是目前各種流行的C/C++開發工具都提供了類庫開發框架來簡化整個開發過程而又不失其固有的靈活高效性,不同的開發語言所提供的類庫開發框架不同,如Borland
C++提供的OWL(Object Windows Library)和 Visual C++提供的MFC(Microsoft Fundmental
Class),這兩種類庫都封裝了大量的Windows
API和Windows的開發元素而使得開發任務簡化,兩種類庫各有其優點,據作者掌握的資料,采用MFC編寫的應用程序執行代碼更小,執行速度也更快,這大概是因為該軟件的開發者是開發Windows操作系統的Microsoft公司的緣故吧,現在MFC正逐漸成為Windows下的類庫開發標準,正被越來越多的其它C/C++編譯工具所支持,如Watcom
C++。使用MC類庫同時配合Visual
C++提供的AppWizard、ClassWizard和AppStudio可以大幅度提高開發效
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -