MFC
微軟基礎類庫(英語:Microsoft Foundation Classes,簡稱MFC)是微軟公司提供的一個類庫(class libraries),以C++類的形式封裝了Windows API,并且包含一個應用程序框架,以減少應用程序開發人員的工作量。其中包含大量Windows句柄封裝類和很多Windows的內建控件和組件的封裝類。
MFC(MicrosoftFoundationClasses)是微軟基礎類庫的簡稱,是微軟公司實現的一個c++類庫,主要封裝了大部分的windows API函數,vc++是微軟公司開發的c/c++的集成開發環境,所謂集成開發環境,就是說利用它可以編輯,編譯,調試,而不是使用多種工具輪換操作,靈活性較大。vc也指它的內部編譯器,集成開發環境必須有一個編譯器內核,例如DevC++其中一個編譯器內核就是gcc。
MFC除了是一個類庫以外,還是一個框架,在vc++里新建一個MFC的工程,開發環境會自動幫你產生許多文件,同時它使用了mfcxx.dll。xx是版本,它封裝了mfc內核,所以你在你的代碼看不到原本的SDK編程中的消息循環等等東西,因為MFC框架幫你封裝好了,這樣你就可以專心的考慮你程序的邏輯,而不是這些每次編程都要重復的東西,但是由于是通用框架,沒有最好的針對性,當然也就喪失了一些靈活性和效率。但是MFC的封裝很淺,所以效率上損失不大。
MFC初學教程
編寫MFC程序,其實跟編寫C++程序一樣,在VS編譯平臺上新建項目,然后一直默認下一步就行,不過有其他需求則需要根據實際情況來添加。建好一個項目后,會出現兩個界面,一個是顯示窗口,一個是編程界面,類似LV中的前面板和程序框圖。在界面右邊有個工具箱,可以根據需要添加控件。
下面主要編寫一個簡單的計算器程序,實現對輸入數的四則運算,主要步驟如下:
1、在對話框中放置6個按鈕控件和3個編輯框控件
具體操作:界面右邊點擊工具箱,根據具體需要選擇具體控件。
2、將3個編輯框控件分別添加float型變量m_edit1、m_edit2、m_edit3
具體操作:選中編輯框點右鍵添加變量,將右邊類別改為value,變量名分別改為m_edit1、m_edit2、m_edit3。
3、將6個個按鈕控件重新命名
具體操作:選中按鈕點擊右鍵屬性,將Caption改為所需要+ - * / 清除 關閉,具體可根據需要來命名。
4、選擇工具箱中Group Box將四則運算框住,然后通過屬性改名字,同時在上方添加靜態文本(Static Text)來編輯命名。
界面主要部分完成,接下來就是編寫代碼,雙擊各個控件,就可自動跳轉到程序編寫部分,主要代碼如下
[html] view plain copyvoid CMFC入門Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知處理程序代碼
UpdateData(true);//從控件獲得數據賦給變量
m_edit3 = m_edit1 + m_edit2;
UpdateData(false);//輸出變量的值到控件
}
void CMFC入門Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知處理程序代碼
UpdateData(true);
m_edit3 = m_edit1 - m_edit2;
UpdateData(false);
}
void CMFC入門Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知處理程序代碼
UpdateData(true);
m_edit3 = m_edit1*m_edit2;
UpdateData(false);
}
void CMFC入門Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知處理程序代碼
UpdateData(true);
if (m_edit2 == 0)
{
MessageBox(_T(“除數不能為0”));
return;
}
m_edit3 = m_edit1 / m_edit2;
UpdateData(false);
}
void CMFC入門Dlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知處理程序代碼
m_edit1 = 0;
m_edit2 = 0;
m_edit3 = 0;
UpdateData(false);
GotoDlgCtrl((CEdit*)GetDlgItem(IDC_EDIT1));//設置焦點在第一個編輯框
}
最后編寫完成,運行一下,彈出一個界面如下:
驗證一下程序,以加法為例,m_edit1輸入18,m_edit2輸入36,得出結果如下所示。
mfc編程入門教程
1.MFC窗口類CWnd
在Windows系統里,一個窗口的屬性分兩個地方存放:一部分放在“窗口類”里頭,如上所述的在注冊窗口時指定;另一部分放在Windows Object本身,如:窗口的尺寸,窗口的位置(X,Y軸),窗口的Z軸順序,窗口的狀態(ACTIVE,MINIMIZED,MAXMIZED,RESTORED…),和其他窗口的關系(父窗口,子窗口…),窗口是否可以接收鍵盤或鼠標消息,等等。
為了表達所有這些窗口的共性,MFC設計了一個窗口基類CWnd。有一點非常重要,那就是CWnd提供了一個標準而通用的MFC窗口過程,MFC下所有的窗口都使用這個窗口過程。至于通用的窗口過程卻能為各個窗口實現不同的操作,那就是MFC消息映射機制的奧秘和作用了。這些,將在后面有關章節詳細論述。
CWnd提供了一系列成員函數,或者是對Win32相關函數的封裝,或者是CWnd新設計的一些函數。這些函數大致如下。
方法/步驟
(1)窗口創建函數
這里主要討論函數Create和CreateEx。它們封裝了Win32窗口創建函數::CreateWindowEx。Create的原型如下:
BOOL CWnd::Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd, UINT nID,
CCreateContext* pContext)
Create是一個虛擬函數,用來創建子窗口(不能創建桌面窗口和POP UP窗口)。CWnd的基類可以覆蓋該函數,例如邊框窗口類等覆蓋了該函數以實現邊框窗口的創建,視類則使用它來創建視窗口。
Create調用了成員函數CreateEx。CWnd::CreateEx的原型如下:
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
CreateEx有11個參數,它將調用::CreateWindowEx完成窗口的創建,這11個參數對應地傳遞給::CreateWindowEx。參數指定了窗口擴展風格、“窗口類”、窗口名、窗口大小和位置、父窗口句柄、窗口菜單和窗口創建參數。
CreateEx的處理流程將在后面4.4.1節討論窗口過程時分析。
窗口創建時發送WM_CREATE消息,消息參數lParam指向一個CreateStruct結構的變量,該結構有11個域,其描述見后面4.4.1節對窗口過程的分析,Windows使用和CreateEx參數一樣的內容填充該變量
(2)窗口銷毀函數
例如:
DestroyWindow函數 銷毀窗口
PostNcDestroy( ),銷毀窗口后調用,虛擬函數
3)用于設定、獲取、改變窗口屬性的函數,例如:
SetWindowText(CString tiltle) 設置窗口標題
GetWindowText() 得到窗口標題
SetIcon(HICON hIcon, BOOL bBigIcon);設置窗口像標
GetIcon( BOOL bBigIcon ) ;得到窗口像標
GetDlgItem( int nID);得到窗口類指定ID的控制子窗口
GetDC(); 得到窗口的設備上下文
SetMenu(CMenu *pMenu); 設置窗口菜單
GetMenu();得到窗口菜單
…
(4)用于完成窗口動作的函數
用于更新窗口,滾動窗口,等等。一部分成員函數設計成或可重載(Overloaded)函數,或虛擬(Overridden)函數,或MFC消息處理函數。這些函數或者實現了一部分功能,或者僅僅是一個空函數。如:
有關消息發送的函數:
SendMessage( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );
給窗口發送發送消息,立即調用方式
PostMessage(( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );
給窗口發送消息,放進消息隊列
…
有關改變窗口狀態的函數
MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE );
移動窗口到指定位置
ShowWindow(BOOL );顯示窗口,使之可見或不可見
…
實現MFC消息處理機制的函數:
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ); 窗口過程,虛擬函數
virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );處理命令消息
…
消息處理函數:
OnCreate( LPCREATESTRUCT lpCreateStruct );MFC窗口消息處理函數,窗口創建時由MFC框架調用
OnClose();MFC窗口消息處理函數,窗口創建時由MFC框架調用
…
其他功能的函數
CWnd的導出類是類型更具體、功能更完善的窗口類,它們繼承了CWnd的屬性和方法,并提供了新的成員函數(消息處理函數、虛擬函數、等等)。
常用的窗口類及其層次關系見圖1-1。
2.在MFC下創建一個窗口對象
MFC下創建一個窗口對象分兩步,首先創建MFC窗口對象,然后創建對應的Windows窗口。在內存使用上,MFC窗口對象可以在棧或者堆(使用new創建)中創建。具體表述如下:
創建MFC窗口對象。通過定義一個CWnd或其派生類的實例變量或者動態創建一個MFC窗口的實例,前者在棧空間創建一個MFC窗口對象,后者在堆空間創建一個MFC窗口對象。
調用相應的窗口創建函數,創建Windows窗口對象。
例如:在前面提到的AppWizard產生的源碼中,有CMainFrame(派生于CMDIFrame(SDI)或者CMDIFrameWnd(MDI))類。它有兩個成員變量定義如下:
CToolBar m_wndToolBar;
CStatusBar m_wndStatusBar;
當創建CMainFrame類對象時,上面兩個MFC Object也被構造。
CMainFrame還有一個成員函數
OnCreate(LPCREATESTRUCT lpCreateStruct),
它的實現包含如下一段代碼,調用CToolBar和CStatusBar的成員函數Create來創建上述兩個MFC對象對應的工具欄HWND窗口和狀態欄HWND窗口:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
…
if (!m_wndToolBar.Create(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0(“Failed to create toolbar\n”);
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0(“Failed to create status bar\n”);
return -1; // fail to create
}
…
}
關于工具欄、狀態欄將在后續有關章節作詳細討論。
在MFC中,還提供了一種動態創建技術。動態創建的過程實際上也如上所述分兩步,只不過MFC使用這個技術是由框架自動地完成整個過程的。通常框架窗口、文檔框架窗口、視使用了動態創建。介于MFC的結構,CFrameWnd和CView及其派生類的實例即使不使用動態創建,也要用new在堆中分配。理由見窗口的銷毀(2.2.5節)。
至于動態創建技術,將在下一章具體討論。
在Windows窗口的創建過程中,將發送一些消息,如:
在創建了窗口的非客戶區(Nonclient area)之后,發送消息WM_NCCREATE;
在創建了窗口的客戶區(client area)之后,發送消息WM_CREATE;
窗口的窗口過程在窗口顯示之前收到這兩個消息。
如果是子窗口,在發送了上述兩個消息之后,還給父窗口發送WM_PARENATNOTIFY消息。其他類或風格的窗口可能發送更多的消息,具體參見SDK開發文檔。
3.MFC窗口的使用
MFC提供了大量的窗口類,其功能和用途各異。程序員應該選擇哪些類來使用,以及怎么使用他們呢?
直接使用MFC提供的窗口類或者先從MFC窗口類派生一個新的C++類然后使用它,這些在通常情況下都不需要程序員提供窗口注冊的代碼。是否需要派生新的C++類,視MFC已有的窗口類是否能滿足使用要求而定。派生的C++類繼承了基類的特性并改變或擴展了它的功能,例如增加或者改變對消息、事件的特殊處理等。
主要使用或繼承以下一些MFC窗口類(其層次關系圖見圖1-1):
框架類CFrameWnd,CMdiFrameWnd;
文檔框架CMdiChildWnd;
視圖CView和CView派生的有特殊功能的視圖如:列表CListView,編輯CEditView,樹形列表CTreeView,支持RTF的CRichEditView,基于對話框的視CFormView等等。
對話框CDialog。
通常,都要從這些類派生應用程序的框架窗口和視窗口或者對話框。
工具條CToolBar
狀態條CStatusBar
其他各類控制窗口,如列表框CList,編輯框CEdit,組合框CComboBox,按鈕Cbutton等。
通常,直接使用這些類。
4.在MFC下窗口的銷毀
窗口對象使用完畢,應該銷毀。在MFC下,一個窗口對象的銷毀包括HWND窗口對象的銷毀和MFC窗口對象的銷毀。一般情況下,MFC編程框架自動地處理了這些。
(1)對CFrameWnd和CView的派生類
這些窗口的關閉導致銷毀窗口的函數DestroyWindow被調用。銷毀Windows窗口時,MFC框架調用的最后一個成員函數是OnNcDestroy函數,該函數負責Windows清理工作,并在最后調用虛擬成員函數PostNcDestroy。CFrameWnd和CView的PostNcDestroy調用delete this刪除自身這個MFC窗口對象。
所以,對這些窗口,如前所述,應在堆(Heap)中分配,而且,不要對這些對象使用delete操作。
(2)對Windows Control窗口
在它們的析構函數中,將調用DestroyWidnow來銷毀窗口。如果在棧中分配這樣的窗口對象,則在超出作用范圍的時候,隨著析構函數的調用,MFC窗口對象和它的Windows window對象都被銷毀。如果在堆(Heap)中分配,則顯式調用delete操作符,導致析構函數的調用和窗口的銷毀。
所以,這種類型的窗口應盡可能在棧中分配,避免用額外的代碼來銷毀窗口。如前所述的CMainFrame的成員變量m_wndStatusBar和m_wndToolBar就是這樣的例子。
(3)對于程序員直接從CWnd派生的窗口
程序員可以在派生類中實現上述兩種機制之一,然后,在相應的規范下使用。
評論
查看更多