1、全稱Microsoft Foundation Class Library,我們稱為微軟基礎類庫,封閉了絕大部分的win32 Api函數,C++文法中的資料結構,程式的執行流程
MFC就是一個庫(動态庫,靜态庫)
MFC還是一個程式架構
2、為什麼使用MFC
基于架構程式設計,提高工作效率,減少開發周期,節約開發成本。
二、幾個重要的頭檔案
afx.h -絕大部分類的聲明頭檔案
afxwin.h -包含了afx.h和windows.h
afxext.h -提供了擴充視窗類的支援(工具欄,狀态欄等)
三、使用MFC
1、使用MFC庫做自己的控制台程式
入口函數 _tmain()不同于以往的main()
CWinApp theApp;-全局程式對象。
注意:
::函數名()-為win32的API函數。
以Afx開頭的函數,為MFC庫裡的全局函數。
2、使用MFC庫做自己的庫程式(MFC AppWizard dll)
規則動态庫:可以被任何程式調用
擴充動态庫:隻能被支援MFC的程式調用
3、MFC視窗程式
單文檔視圖構架程式。
CFrameWnd-架構視窗類;
CWinApp-應用程式類,負責管理整個程式的執行流程;
CDocument-文檔類,負責管理資料(資料的提取、轉換、存儲等操作);
CView-視圖視窗類,負責顯示資料
多文檔視圖構架程式。
CMDIChildWnd-子架構視窗類,負責管理子架構視窗。
CMDIFrameWnd-主架構視窗類
對話框程式
CDialog-對話框類
四、MFC類的介紹
CObject -mfc庫絕大部分類的基類,封裝了MFC庫中最基本的一些機制,運作時類資訊機制/動态建立機制/序列化機制.
CCmdTarget-消息映射機制基類
CWinThread/CWinApp-應用程式類
CDocTemplate及其子類 -文檔模版類
CDocument及其子類-文檔類,封裝了對各種資料的操作。
Exceptions - 異常類,封裝了MFC中的各種異常情況。
CFile-文操作類
CWnd -所有視窗類基類
FrameWindows 架構視窗類,封裝了對各種架構視窗的操作
ControlBars-各種工具欄類,封閉了對各種工具欄的操作
Dialog Boxes 對話框類。
Views 視圖視窗類
Controls 控件類
CDC/CGdiObject 封裝了繪圖操作
CArray/AList/CMap 對C++中的資料的封裝,以C開頭。
現在學習時,MFC都是建立Win32 Application程式,然後通過下列步驟改為MFC程式,隻有一步步了解怎麼去手動建立MFC,以後通過MFC向導自動生成的大量MFC代碼我們才能看得懂。
1、删除主程式cpp中的入口函數
2、将stdafx.h中的windows.h改為afxwin.h
3、工程-設定 中選擇使用MFC庫
4、自定義架構類和程式類,繼承自MFC類,并重寫CWinApp的InitInstance方法:
class CMyFrameWnd:public CFrameWnd
{
};
class CMyWinApp:public CWinApp
public:
CMyWinApp();
virtual BOOL InitInstance();
CMyWinApp::CMyWinApp()
}
BOOL CMyWinApp::InitInstance()
CMyFrameWnd *pFrame=new CMyFrameWnd;
pFrame->Create(NULL,"MFC base");
m_pMainWnd=pFrame;
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return true;
5、建立一個程式類對象(觸發點):
CMyWinApp theApp;
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();//擷取目前程式子產品狀态資訊
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;//擷取目前線程狀态資訊
pThreadState->m_pCurrentWinThread = this;//theapp全局對象資訊指派
pModuleState->m_pCurrentWinApp = this;
ASSERT(bool表達式);//如果表達式不成立,則彈出錯誤,不往下執行
全局函數:AfxGetApp(),AfxGetThread() 擷取theApp位址
AfxMessageBox();//彈出消息
vc6中,檢視-調試視窗-call stack 可以看到被誰調用
可重寫(前加virtual):
BOOL CMyWinApp::InitApplication();
BOOL CMyWinApp::InitInstance()//初始化
int CMyWinApp::Run()//運作
BOOL CMyWinApp::OnIdle(LONG lcount);//空閑時處理
int CMyWinApp::ExitInstance();
示例代碼:
AfxGetInstanceHandle();//全局句柄
1、加載菜單
2、調用CreateEx 設計、注冊視窗類
PreCreateWindow():
WNDCLASS wndcls;wndcls.lpfWinProc=DefWindowProc;
AfxRegisterWithIcon(),AfxRegisterClass()
::RegisterClass注冊一個局部視窗類,類名“AfxFrameOrView42sd”,預設處理函數。
AfxHookWindowCreate(pFrame) 埋下勾子
CHandleMap* pMap = afxMapHWND(TRUE);
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//映射對象儲存到全局變量
pState->m_pmapHWND = new CHandleMap(...);
pMap->SetPermanent(m_hWnd = hWndNew, this);
//pFrame->m_hWnd 為視窗句柄。
CWnd* pWnd=CWnd::FromHandlePermanent(hWnd);
//pState->m_pmapHWND->LookupPermanent(HANDLE h)成員,可通過視窗句柄擷取pFrame
::CreateWindowEx函數,建立視窗
3、鈎子處理函數
将架構對象位址和視窗句柄建立一一對應關系。
利用::SetWindowLong,将視窗處理函數更改為AfxWndProc.
----------MSDN Library Visual Studio 6.0
//埋下勾子
HHOOK SetWindowsHookEx(
int idHook, // 勾子類型
HOOKPROC lpfn, // 處理函數(不同類型不同)
HINSTANCE hMod, // 程序句柄,NULL時不限制範圍
DWORD dwThreadId // 線程ID
);
//勾子類型為WH_CBT時的處理函數
LRESULT CALLBACK CBTProc(
int nCode, // hook code
WPARAM wParam, // 建立好的視窗句柄
LPARAM lParam // depends on hook code
//勾子處理函數修改預設處理函數
WNDPROC afxWndProc = AfxGetAfxWndProc();
oldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC,(DWORD)afxWndProc);
//修改視窗處理函數
LONG SetWindowLong(
HWND hWnd, // 視窗句柄
int nIndex, // 傳入:GWL_WNDPROC
LONG dwNewLong // 視窗處理函數位址
//全局變量資訊
_AFX_THREAD_STATE* pThreadState=_afxThreadState.GetDate();
::GetCurrentThreadId();//擷取目前線程ID
pThreadState->m_pWndInit = pWnd;//指派到全局變量
::CreateWindowEx() //此函數處理完後直接進入勾子處理函數
重寫消息處理函數
LRESULT CMyFrameWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
switch(message)
case WM_CREATE:
AfxMessageBox("WM_CREATE");
break;
return CFrameWnd::WindowProc(message,wParam,lParam);
示例: