初學MFC基本常識

在MFC程序中,我們並不經常直接調用Windows API,而是從MFC類創建對象並調用屬於這些對象的成員函數.也就是說MFC封裝了Windows API 你說你喜歡C++而MFC換一種說法就是一個用C++寫的一個函數庫 然後你來調用 只不過這個類不是你寫的
MFC提供數百個類,最重要的、也是編寫任何VC++應用程序都必不可少的兩個類CWinApp和CFrameWnd,這兩個類是編寫複雜龐大應用程序的基石。
1>封裝特性:構成MFC框架的是MFC類庫而MFC類庫又是C++的一個類庫。這些類封裝WIN32應用程序編程接口,OLE(Object Link Embed 對象鏈接嵌入)特性,ODBC和DAO數據訪問的功能。
2>繼承特性:MFC抽象出了衆多類的共同特性,並設計出一些基類作爲實現其他類的基礎,這些類中最重要的類是CObject類和CCmdTarget類,程序員可以從適當的MFC類中派生出自己的類,實現特定的功能達到編程的目的。
3>虛擬和消息映射:MFC是以C++爲基礎,當然支持虛函數,但作爲一個編程框架必須要解決的是效率問題:如果MFC僅僅通過虛函數來支持動態約束必然會產生大量的虛函數表這樣編程框架過於臃腫而且消耗更多的內存。但是MFC建立了消息映射機制這樣降低了內存的使用卻大大提高了效率
消息映射是一個將消息和成員函數相互關聯的表,當應用程序的框架窗口接收到一個消息時,MFC將搜索該窗口的消息映射,如果存在一個處理消息的處理程序,那麼就調用該處理程序.
它通過宏來實現消息到成員函數的映射,而且這些函數不必是虛擬的成員函數,這樣不需要爲消息映射函數生成一個很大的虛擬函數表(V表),節省內存。
MFC消息映射機制:
將消息與消息處理函數聯繫起來,形成一一對應的機制。
消息映射宏
聲明: DECLARE_MESSAGE_MAP
定義:
BEGIN_MESSAGE_MAP
ON_COMMAND
ON_CONTROL
ON_MESSAGE
END_MESSAGE_MAP
MFC主要組成部分:類、宏和全局函數。
類是MFC中最主要的內容。MFC類是以層次結構方式組織起來的。MFC中的類分成兩部分,除了一些輔助類,大多數的MFC類是直接或間接從根類CObject派生而來。
MFC宏主要功能:消息映射、運行時對象類型服務、診斷服務、異常處理。
MFC約定:全局函數以“Afx”爲前綴,全局變量以“afx”爲前綴
MFC類的層次關係
CObject項目類)->CCmdTarget(消息響應類)->
{
CWinThread(線程類)->CWinApp(Window應用程序類)
CDocument(文檔類)
CWnd(窗體類)->[
CFrameWnd(框架類)
CView(視圖類)
]
}

CObject類由於MFC中大部分類是從CObject類繼承而來的,CObject類描述了幾乎所有的MFC類的一些公共特性,CObject類爲程序員提供了對象診斷、運行時類型識別和序列化等功能。
CCmdTarget類由CObject類直接派生而來,它負責將消息發送到能夠響應這些消息的對象。它是所有能進行消息映射的MFC類的基類。
CWinApp類在任何MFC應用程序中有且僅有一個CWinApp派生類的對象,它代表了程序中運行的主線程,也代表了應用程序本身。 CWinApp類取代了WinMain()主函數在SDK應用程序中的地位。傳統SDK應用程序WinMain()函數完成的工作。現在由類CWinApp的InitApplication(),InitInstance()和Run()三個成員函數承擔。
CWnd類由CCmdTarget類直接派生而來,該類及其派生類的實例是一個窗口。CWnd類代表了MFC中最基本的GUI對象,它是一個功能最完善、成員函數最多的MFC類。
CFrameWnd類是CWnd類的派生類,主要用來掌管一個窗口,它取代了SDK應用程序中窗口函數WndProc()的地位。CFrameWnd類的對象是一個框架窗口,包括邊框、標題欄、菜單、最大化按鈕、最小化按鈕和一個激活的視圖。
CDocument類在應用程序中作爲用戶文檔類的基類,它代表了用戶存儲或打開的一個文件。
CView類是MFC中一個很基本的類,它作爲其它MFC視圖類和用戶視圖派生類的基類。
從API編程到MFC編程的過渡:
WinMain()
{ 初始化WNDCLASS
註冊窗體結構
創建窗口 ->>>>>>>>應用程序類CWinApp
顯示窗口
消息循環
}

WndProc()
{ switch(…)
{case:…} ->>>>>>>>>框架窗口類CFrameWnd
}

MFC Object和Windows Object的對應關係:
描述 Windows句柄 MFC Object
窗口 HWND CWnd
設備上下文 HDC CDC
菜單 HMENU CMenu
筆 HPEN CPen
刷子 HBRUSH CBrush
字體 HFONT CFont
位圖 HBITMAP CBitmap
套接字 SOCKET CSocket

三、手工創建一個MFC應用程序:
注意:創建MFC程序,要創建一個Win32空項目,並要選擇項目屬性中的”在共享DLL文件中使用MFC,然後新建我們的文件
例子:在”hello.h”頭文件中添寫如下代碼:
class CMyApp:public CWinApp
{
public:
virtual BOOL InitInstance();//虛函數
};
class CMainWindow:public CFrameWnd
{
public:
CMainWindow();
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP();//聲明消息映射
};
在”hello.cpp”源文件中添寫如下代碼:
#include <afxwin.h>
#include “hello.h"
CMyApp myApp;
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;

m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP() //消息映射
CMainWindow::CMainWindow() //構造函數初始化
{
Create(NULL,“我的第一個MFC應用程序”);//創建窗體
}
void CMainWindow::OnPaint()
{ CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
dc.DrawText("Hello MFC",-1,&rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
CWinApp是應用程序類,在MFC應用程序中必須從這個類派生出一個類,該派生類是MFC應用程序的入口
必須定義這個派生類的對象,並且只能有一個這個對象代表整個應用程序。
成員函數:InitInstance()
功能:初始化應用程序實例和窗口實例,
虛函數CWinApp::InitInstance必須在派生類中重寫。在InitInstance函數中,編寫初始化代碼,如:
創建一個窗口
顯示一個窗口
CFrameWnd類
作用:爲應用程序提供一個窗口,同時實現消息處理功能。
成員函數: Create()
功能:創建窗體,將之賦於CFrameWnd對象上。
BOOL Create(窗口類型, 窗口標題,顯示風格,顯示區域,符窗口句柄,菜單,擴展顯示風格,上下文對象)共有8個參數,前兩個必須給出,後6個可以默認。
MFC應用程序的核心就是基於CWinApp類的應用程序對象,CWinApp提供了消息循環來檢索消息並將消息調度給應用程序的窗口.我們在編寫MFC應用程序時,要包含afxwin.h,
一個MFC應用程序可以有且僅有一個應用程序對象,對象必須聲明爲在全局範圍內有效(也就是全局對象),以便它在程序開始時即在內存中被實例化
我們的Hello MFC的應用程序類被命名爲CMyApp,它在hello.cpp中用如下語句進行了實例化:
CMyApp myApp;
CMyApp的類聲明在hello.h中代碼如下:
class CMyApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CMyApp沒有聲明任何的數據成員,只是重寫了一個從CWinApp類中繼承來的函數,在應用程序的生存期內InitInstance的調用比較早,是在應用程序開始運行以後而窗口創建之前,除非InitIstance創建一個窗口,否則應用程序是不會有窗口,這正是爲什麼即使最小的MFC應用程序也必須從CWinApp派生出一個類並重寫CWinApp::InitIstance的原因
InitInstance函數:CWinApp::InitInstance是一個虛函數,其默認操作僅包含一條語句:return TRUE;
InitInstance是用來執行程序每次開始時都需要進行的初始化工作最好的地方
在hello.cpp中,CMyApp的InitInstance通過實例化hello的CMainWindow類來創建hello窗口,語句:
m_pMainWnd = new CMainWindow;

構造了一個CMainWindow對象指針,並將其地址複製到了應用程序對象的m_pMainWnd數據成員中,窗口創建以後,InitInstance就會通過CMainWindow指針調用ShowWindow和UpdateWindow函數顯示它:

m_pMainWnd->ShowWindow(m_nCmdShow);

m_pMainWnd->UpdateWindow();
ShowWindow和UpdateWindow是所有窗口對象共用的CWnd成員函數其中包括CFrameWnd類的對象,CMainWindow就是從CFrameWnd派生出來的.
要從MFC程序調用一個常規的Windows API函數,需要在函數名稱前添加一個全局運算符:: 例如:::UpdateWindow();
通過生成窗口對象並調用其Create函數,MFC應用程序可以創建一個窗口,在CMyApp::InitInstance中,hello創建了一個CMainWindow對象,CMainWindow的構造函數生成在屏幕上看到的窗口:
Create(NULL,”我的第一個MFC應用程序”);
CPaintDC dc(this);
MFC的CPaintDC類是從MFC的CDC類派生的,CDC類封裝了Windows設備環境,以及包含了繪製到屏幕、打印機和其他設備的幾十個成員函數
在MFC中如何處理消息呢?
在SDK中我們利用的是消息循環和窗口過程函數對消息進行消息處理.
在MFC中我們用的是消息映射機制.
下面是將消息映射添加到一個類中需要做的全部工作.
1>通過將DECLARE_MESSAGE_MAP語句添加到類聲明中,聲明消息映射.
2>通過放置標識消息的宏來執行消息映射,相應的類將在對BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的調用之間處理消息
3>添加成員函數來處理消息
1、構造CWinApp派生類的對象
2、系統調用WinMain()
3、WinMain調用InitInstance,在該函數中創建CFrameWnd派生類對象,調用Create函數創建窗口、調用ShowWindow函數顯示窗口。
4、之後內部機制調用Run,接受用戶的消息,並將消息導向默認的處理函數。當接收到WM_QUIT消息時,Run內部調用ExitInstance,退出程序。
MFC採用消息映射(Message Map)機制取代C/C++語言中的switch-case結構來處理消息。
消息映射:在MFC中把消息處理函數和它所要處理的特定的消息連接起來的一種機制。
它通過宏來實現消息到成員函數的映射,而且這些函數不必是虛擬的成員函數,這樣不需要爲消息映射函數生成一個很大的虛擬函數表(V表),節省內存。
MFC消息映射機制包括一組消息映射宏。一條消息映射宏把一個Windows消息和其消息處理函數聯結起來。
MFC應用程序框架提供了消息映射功能。
在類的實現源文件中用BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏來定義消息映射。
在類定義的結尾用DECLARE_MESSAGE_MAP()宏來聲明使用消息映射。
Hello的CmainWindow類只處理一種消息類型—WM_PAINT,因此其消息映射的實現如下所示:
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd);
ON_WM_PAINT()
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP開始了消息映射,並標識了消息映射所屬的類和該類的基類
END_MESSAGE_MAP()結束消息映射.
ON_WM_PAINT()在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()之間,稱做消息條目,在MFC爲100多種Window消息提供了宏.
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
afx_msg 醒目地暗示OnPaint是一個消息處理程序,
DECLARE_MESSAGE_MAP()聲明消息映射
MFC把消息主要分爲三大類:
(1)、標準Windows消息(WM_XXX)
使用宏:ON_WM_XXX() 特點:有默認的消息處理函數
(2)、命令消息:(WM_COMMAND)
來自於菜單、工具條、按鈕等的消息
使用宏: ON_COMMAND(命令按鈕標識符ID,消息處理函數)
特點:由用戶指定消息處理函數
3、”Notification消息” (通知消息) 由控件產生:
BOOL 布爾值,取值爲TRUE或者FALSE
BSTR 32爲字符指針
BYTE 8位整數無符號的
COLORREF 32位數值代表一個顏色值
DWORD 32位整數無符號的
LONG 32位整數帶符號的
LPCTSTR 32位指針,指向一個常字符串
LPVOID 32位指針,指向一個爲指定類型的數據
MFC特有的數據類型:
1>POSITION :一個數值,代表數組或者鏈表中元素的位置,在MFC中常用於數據處理類
2>LPRECT:32位指針,指向一個不變的矩形區域結構

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