第二天:Microsoft基本類庫應用程序框架
◎MFC是C++的Microsoft Windows API,如果想要開發WINDOWS的應用程序當然VC/MFC是開發環境的首選。
◎MFC產生的應用程序使用了標准化的結構。(我現在還體會不出這點的優勢所在,請高手指點)
◎MFC產生的應用程序短而運行速度快。這應該說的是可以很容易的建立動態連接,其實程序還是需要大量的DLL,不過由於WINDOWS上有很多可以用DLL所以應用程序很短,我是這樣想的不知對否。
◎VC++工具降低了編碼的復雜性。這點不容質疑比起TC方便太多了。
◎MFC庫功能非常豐富。書上列出了MFC從1.0--4.21的一些特性,我就不廢話了,大家應該看看。
這一章節主要介紹了MFC庫的優點,其實我本人認為在某些特定環境下其實MFC不一定就象說的那樣好。我想不會有人用純VC做MIS系統吧,太累了。我是這樣理解編程序的,如果把學編程看成學武的話,C/C++語言及編程思想(OOP)是內功,API是基本功(編程思想是內功、API是基本功這適用於任何WIN32編程,不論Visual
C++、Delphi、C++Builder、VB......),VC/MFC應該不同武功其中的一種,不同的學習方法效果不一樣,只要下工夫也都可以達到一定的境界。真正的高手是有著深厚的內功,扎實的基本功,至於武功招數無所謂了,隨便一站不丁不八全無破綻,無招勝有招了。對不住扯遠了。
C++可以通過類庫來進行擴展,我們除了可以使用隨編譯器提供的類庫外還可以很方便使用軟件公司銷售的類庫產品,甚至可以自己開發。而應用程序框架是一種類庫的超集,它定義了程序的結構。
下面給出兩個示例程序(一個是書上的一個是我寫的):
雷神建議:雖然現在很多書都附CD,CD上有書中所有示例的源代碼,但還是應該親自在VC6用手敲進去。這樣可以加深印象以及感受一下編譯除錯後程序正確運行時的樂趣,因為是純手工打造。自從我敲了近一百個代碼示例後,由於筆誤的BUG就很少了,打字速度也提高了。而且最好在原示例代碼的基礎上做些改動例如別千篇一律的顯示HELLO
WORLD!換點別的,這樣做也可以加深對示例程序的理解。
我的HELLO WORLD用AppWizard向導創建一個顯示一個字符串的單文檔程序,只需要敲入一行語句,主要是體驗MFC的強大功能。
1、打開VC++6從菜單選擇NEW,給項目命名為”MyApp01“。
2、選擇MFC AppWizard[exe] 選項,除STEP 1選擇單文檔外其他STEP缺省。
3、在Class View選擇CMyApp01View類的OnDraw()成員函數雙擊會在C++編譯器看到以下內容
void CMyApp01View::OnDraw(CDC* pDC)
{
CMyApp01Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
在 // TODO: add draw code for native data here的位置增加一行代碼
void CMyApp01View::OnDraw(CDC* pDC)
{
CMyApp01Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(10,10,"雷神願意和所有學VC的朋友共同進步!"); //<-----------增加的一行
// TODO: add draw code for native data here
}
完了,就這麼簡單。編譯運行。看到了嗎?這個程序具備WINDOWS程序的所有特性,例如有菜單、工具條、狀態欄、最大化、關閉、甚至還有關於對話框、打印預覽.....全了,這就是AppWizard通過MFC動態創建的一個應用程序。從這個小例子可以看出用VC/MFC設計WINDOWS程序多麼方便。下面我們看看書上的例子,以便更進一步了解應用程序框架。
書上的例子:
1、先建立一個Win32 Application的應用程序。
2、選擇Project->Add to project->Files,分別創建一個名為MyApp.h和一個名為MyApp.cpp的文件。
3、添加代碼:(最好照敲以下代碼到編譯器,別用Ctrl+C/Ctrl+V)
//***********************************************
// MyApp.h
//
class CMyApp:public CWinApp //見下②
{
public:
virtual BOOL InitInstance();
};
class CMyFrame:public CFrameWnd
{
public:
CMyFrame();
protected:
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
//*****************************************************
// MyApp.cpp
//
#include "afxwin.h"
#include "myapp.h"
CMyApp theApp;//建立一個CMyAPP對象見下②
BOOL CMyApp::InitInstance ()
{
m_pMainWnd=new CMyFrame();
m_pMainWnd->ShowWindow (m_nCmdShow);
m_pMainWnd->UpdateWindow ();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMyFrame,CFrameWnd)
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
END_MESSAGE_MAP()
CMyFrame::CMyFrame(){
Create(NULL,"MYAPP Application");
}
void CMyFrame::OnLButtonDown (UINT nFlags,CPoint point)
{
TRACE("Entering CMyFrame::OnLButtonDown - %lx,%d,%d\n",
(long)nFlags,point.x ,point.y);
}
void CMyFrame::OnPaint ()
{
CPaintDC dc(this);
dc.TextOut (0,0,"Hello World!");
}
4、編譯運行,報錯。為什麼呢?原來還沒有添加MFC的支持,在Project Setting選項General屬性頁選擇”Use MFC
in a Static Library"
5、再Ctrl+F5,哈成功了。
讓我們看看這個程序中的一些元素。
①WinMain函數:並非不存在只是已經被隱藏在應用程序框架內部。
②CMyApp類:CMyApp類的對象代表一個應用程序,CWinApp基類決定它的大部分行為。
③應用程序的啟動:當開始運行應用程序時WINDOWS會調用WinMain函數,WinMain會查找該應用程序的全局對象theApp。
④CMyApp::InitInstance成員函數:發現theApp後自動調用重載的虛函數InitInstance來完成主窗口的構造和顯示工作。記住這個函數。
⑤CWinApp::Run成員函數:WinMain在調用InitInstance之後緊接著調用Run函數,它被隱藏在基類中負責傳遞應用程序的消息給相映的窗口。(我把它理解為好象SDK的窗口的過程函數不知對不對)
⑥CMyFrame類:此類的對象代表著應用程序的主窗口。它的構造函數調用基類CFrameWnd的Create函數創建具體的窗口結構。
⑦CMyFrame::OnLButtonDown函數:演示消息處理機制,當鼠標坐鍵被按下這一事件被映射到CMyFrame的OnLButtonDown函數上,如果你選擇F5進行編譯運行的話可以在調試窗口看到TRACE宏顯示的類似下面的信息
Entering CMyFrame::OnLButtonDown - 1,309,119
Entering CMyFrame::OnLButtonDown - 1,408,221
⑧CMyFrame::OnPaint函數:應用程序每次重新繪制窗口都需要調用此函數,將顯示"Hello World!"放在這裡是因為每次窗口發生變化時保證"Hello
World!"被顯示,你可以試著將語句:
CPaintDC dc(this);
dc.TextOut (0,0,"Hello World!");
寫在別出,例如寫在
void CMyFrame::OnLButtonDown (UINT nFlags,CPoint point)
{
TRACE("Entering CMyFrame::OnLButtonDown - %lx,%d,%d\n",
(long)nFlags,point.x ,point.y);
CPaintDC dc(this);
dc.TextOut (0,0,"Hello World!");
}
運行後當點擊左鍵時顯示"Hello World!",但當窗口最小化再最大化時"Hello World!"不見了。
⑧關閉應用程序:用戶關閉應用程序時會有一系列事件發生。首先CMyFrame對象被刪除,然後退出Run,進而退出WinMain,最後刪除CMyApp對象。
通過上面的示例我們看見程序的大部分功能包含在基類CWinApp和CFrameWnd中,我們只寫了很少的函數,便可以完成很復雜的功能。所以應用程序框架不僅僅是一種類庫,它還定義了應用程序的結構,除了基類外還包括WinMain函數,以及用來支持消息處理、診斷、DLL、等都包含在應用程序框架中。
(未完待續)