生活随笔
收集整理的這篇文章主要介紹了
MFC封装API
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、Win32Application Architecture
一個Win32 Application Architecture的代碼結構如下:
| LRESULT CALLBACK WinWordsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);? //定義回調處理消息函數(shù) ? int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ ???????? // 創(chuàng)建一個窗口類分為三步:1.設計窗口類 2.注冊窗口類 3.創(chuàng)建窗口 4.顯示及更新窗口 ???????? // 步驟1.設計窗口類 ???????? WNDCLASS wc; …… ???????? // 步驟2:注冊窗口類 ???????? RegisterClass(&wc); ???????? // 步驟3:創(chuàng)建窗口 ???????? HWND hw = NULL;?? ???????? hw = CreateWindow("Icanth2011", "My Fist Win32 Application Project!~", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL); ???????? // 步驟4:顯示及更新窗口 ???????? ShowWindow(hw, SW_SHOWNORMAL); ???????? UpdateWindow(hw); ???????? // 消息循環(huán) ???????? MSG msg; ???????? BOOL bRet; ???????? while((bRet=GetMessage(&msg, NULL, 0, 0))!=0){ ?????????????????? if(-1 == bRet){ ??????????????????????????? return -1; ?????????????????? } ?????????????????? TranslateMessage(&msg); ?????????????????? DispatchMessage(&msg); ???????? } ???????? return msg.wParam; } | ? |
?
由此可見,Win32 Application 程序的組成分為如下幾個部分:
1.???????找到WinMain程序入口,并開始執(zhí)行
2.???????創(chuàng)建并設計窗口類
3.???????注冊窗口類
4.???????創(chuàng)建窗口
5.???????顯示及更新窗口
6.???????循環(huán)獲取消息,經(jīng)處理,交還系統(tǒng)讓其調用相關回調消息處理函數(shù)進行處理。
?
二、MFCArchitecture
由于Windows API過多,不方便程序員使用,并且非面對象。于是MFC被用于對Windows API進行封裝,MFC始終實際運行過程就是Win32 Application程序的運行過程。
?
1.????? MFC的項目結構
利用MFC AppWipzard自動生成的項目包括五個文件:CMyFirstMFCApp、CMainFrame、CFirstMFCDoc、CMyFirstCView、CAboutDlg。CMyFirstMFCApp繼承自CWinApp,CMainFrame、CMyFirstCView、CAboutDlg都繼承自CWnd,CFirstMFCDoc繼承自CDocument,體現(xiàn)“文檔/視圖”結構。其項目結構如下所示:
?
2.????? MFC的執(zhí)行過程
對于MFC框架運行過程進行剖析,最好的資料是MFC源代碼,VC6位于“\Microsoft Visual Studio\VC98\MFC\SRC”下。執(zhí)行過程如下:
| 定義theApp(:CMyFistMFCApp) ?????????????????? ——>執(zhí)行構造函數(shù):CWinApp()->CMyFistMFCApp()-> ???????????????????????????????????? ——>程序入口_tWinMain (宏,定義為WInMain) ——>執(zhí)行AftxWinMain ? | ? |
?
?
?
?
?
2.1? MFC的WinMain
在\SRC\APPMODUL.CPP中,可找到如下代碼:
| MFC\SRC\APPMODUL.CPP: ? extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, ???????? LPTSTR lpCmdLine, int nCmdShow) { ???????? // call shared/exported WinMain ???????? return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
而其中_tWinMain其實就是WinMain函數(shù)的宏,定義如下:
?
| #define _tmain????? main #define _tWinMain?? WinMain #ifdef? _POSIX_ #define _tenviron?? environ ? | ? |
?
?
?
?
由此可見,WinMain中調用AfxWinMain進行處理。MFC包含此文件,故將找到此入口并自動調用執(zhí)行。
?
2.2? theApp全局對象
在Project\CMyFirstMFCApp.CPP中,可找到一行代碼發(fā)下:
| Project\CMyFirstMFCApp.CPP: ? / // The one and only CMyFistMFCApp object CMyFistMFCApp theApp; ? | ? |
?
?
?
?
?
當定義theApp時,將先執(zhí)行CWinApp(\MFC\SRC\APPCORE.CPP)的構造函數(shù):
| \MFC\SRC\APPCORE.CPP: ? CWinApp::CWinApp(LPCTSTR lpszAppName) // 有在該類定義時有默認值NULL { ???????? if (lpszAppName != NULL) ?????????????????? m_pszAppName = _tcsdup(lpszAppName); ???????? else ?????????????????? m_pszAppName = NULL; ? ???????? // initialize CWinThread state ???????? AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); ???????? AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread; ???????? ASSERT(AfxGetThread() == NULL); ???????? pThreadState->m_pCurrentWinThread = this; ???????? ASSERT(AfxGetThread() == this); ???????? m_hThread = ::GetCurrentThread(); ???????? m_nThreadID = ::GetCurrentThreadId(); ? ???????? // initialize CWinApp state ???????? ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please ???????? pModuleState->m_pCurrentWinApp = this; // handle,this代表子類CMyFirstMFCApp對象 ???????? ASSERT(AfxGetApp() == this); …… } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
2.3? AfxWinMain(WINMAIN.CPP)
?
1.AfxWindMain定義
?
| \MFC\SRC\WINMAIN.CPP: ? int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, ???????? LPTSTR lpCmdLine, int nCmdShow) { ???????? CWinThread* pThread = AfxGetThread(); ???????? CWinApp* pApp = AfxGetApp(); ???????? if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) ???????? if (pApp != NULL && !pApp->InitApplication()) ?????????????????? goto InitFailure; ???????? if (!pThread->InitInstance()) ???????? { ?????????????????? if (pThread->m_pMainWnd != NULL) ?????????????????? { ??????????????????????????? pThread->m_pMainWnd->DestroyWindow(); ?????????????????? } ?????????????????? goto InitFailure; ???????? } ???????? nReturnCode = pThread->Run(); } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
2.AfxGetThread
AfxGetThread(THRDCORE.CPP)中調用AfxGetApp,和afxGetApp返回同值,代碼如下所示:
| \MFC\SRC\ THRDCORE.CPP: ? CWinThread* AFXAPI AfxGetThread() { ???????? // check for current thread in module thread state ???????? AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); ???????? CWinThread* pThread = pState->m_pCurrentWinThread; ???????? // if no CWinThread for the module, then use the global app ???????? if (pThread == NULL) ?????????????????? pThread = AfxGetApp(); ???????? return pThread; } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
3.AfxGetApp
AfxGetApp(AFXWIN1.INL)中定義:
| AFXWIN1.INL: ? _AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp(){ return afxCurrentWinApp; } ? | ? |
?
?
?
?
?
而afxCurrentWinApp定義位于AFXWIN.H文件中,如下:
| AFXWIN.H: ? #define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp ? | ? |
?
?
?
?
即為CWinApp構造函數(shù)時初始化為this的m_pCurrentWinApp。
?
4.InitInstance
類CWinAPP(APPCORE.CPP)中InitInstance函數(shù)定義為:
| \MFC\SRC\ APPCORE.CPP: ? // overrides for implementation virtual BOOL InitInstance(); ? | ? |
?
?
?
?
類InitInstance即為虛函數(shù),根據(jù)多態(tài)性,將調用CMyFirstMFCApp類的InitInstance。
?
2.4? InitInstance(CMyFirstMFCAPP.CPP)
| \MFC\SRC\ CMyFirstMFCAPP.CPP: ? BOOL CMyFistMFCApp::InitInstance() { ???????? CSingleDocTemplate* pDocTemplate; ???????? pDocTemplate = new CSingleDocTemplate( ?????????????????? IDR_MAINFRAME, ?????????????????? RUNTIME_CLASS(CMyFistMFCDoc), ?????????????????? RUNTIME_CLASS(CMainFrame),?????? // main SDI frame window ?????????????????? RUNTIME_CLASS(CMyFistMFCView)); ???????? AddDocTemplate(pDocTemplate); ???????? m_pMainWnd->ShowWindow(SW_SHOW); ???????? m_pMainWnd->UpdateWindow(); } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
2.5? MFC框架窗口
CFirstMyMFC有兩個窗口,其中一個是CMainFrame。
?
2.5.1 設計和注冊窗口
?
1.???????CMainFrame::PreCreateWindow定義(\Project\CMainFrame.cpp)
| \MFC\SRC\ CMyFirstMFCAPP.CPP: ? BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { ???????? if( !CFrameWnd::PreCreateWindow(cs) ) ?????????????????? return FALSE; ???????? return TRUE; } ? | ? |
?
?
?
?
?
?
2.???????CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) (\MFC\SRC\WINFRM.CPP)
?
?
| \MFC\SRC\ CMyFirstMFCAPP.CPP: ? BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) { ???????? if (cs.lpszClass == NULL) ???????? { ?????????????????? VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); ?????????????????? cs.lpszClass = _afxWndFrameOrView;? // COLOR_WINDOW background ???????? } ???????? return TRUE; } ? | ? |
?
?
?
?
?
?
?
?
?
其中,AfxDeferRegisterClass即為AfxEndDeferRegisterClass的宏定義,位于AFXIMPL.H文件中:
| AFXIMPL.H: ? #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) ? | ? |
?
?
?
?
3.???????AfxEndDeferRegisterClass?(位于WINCORE.CPP中)
此處指定DefWindowProc函數(shù)來處理回調消息。 (!~)
| MFC\SRC\WINCORE.CPP: ? BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister) { ???????? // mask off all classes that are already registered ???????? AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); ???????? fToRegister &= ~pModuleState->m_fRegisteredClasses; ???????? if (fToRegister == 0) ?????????????????? return TRUE; ???????? LONG fRegisteredClasses = 0; ???????? // common initialization ???????? WNDCLASS wndcls; ???????? memset(&wndcls, 0, sizeof(WNDCLASS));?? // start with NULL defaults ???????? wndcls.lpfnWndProc = DefWindowProc; ???????? wndcls.hInstance = AfxGetInstanceHandle(); ???????? wndcls.hCursor = afxData.hcurArrow; ???????? INITCOMMONCONTROLSEX init; ???????? init.dwSize = sizeof(init); ???????? // work to register classes as specified by fToRegister, populate fRegisteredClasses as we go ???????? if (fToRegister & AFX_WND_REG) ???????? { ?????????????????? // Child windows - no brush, no icon, safest default class styles ?????????????????? wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; ?????????????????? wndcls.lpszClassName = _afxWnd; ?????????????????? if (AfxRegisterClass(&wndcls)) ??????????????????????????? fRegisteredClasses |= AFX_WND_REG; ???????? } ???????? …… } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
4.???????AfxRegisterClass? (位于WINCORE.CPP中)
| MFC\SRC\WINCORE.CPP: ? BOOL AFXAPI AfxRegisterClass(WNDCLASS* lpWndClass) { ???????? WNDCLASS wndcls; ???????? if (GetClassInfo(lpWndClass->hInstance, lpWndClass->lpszClassName, ?????????????????? &wndcls)) ???????? { ?????????????????? // class already registered ?????????????????? return TRUE; ???????? } ???????? if (!::RegisterClass(lpWndClass)) ???????? { ?????????????????? TRACE1("Can't register window class named %s\n", ??????????????????????????? lpWndClass->lpszClassName); ?????????????????? return FALSE; ???????? } ???????? return TRUE; } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
2.5.2 創(chuàng)建窗口
1. CFrameWnd::Create ?(WINFRM.CPP)
| MFC\SRC\WINFRM.CPP: ? BOOL CFrameWnd::Create(LPCTSTR lpszClassName, ???????? LPCTSTR lpszWindowName, ???????? DWORD dwStyle, ???????? const RECT& rect, ???????? CWnd* pParentWnd, ???????? LPCTSTR lpszMenuName, ???????? DWORD dwExStyle, ???????? CCreateContext* pContext) { ???????? HMENU hMenu = NULL; ???????? if (lpszMenuName != NULL) ???????? { ?????????????????? // load in a menu that will get destroyed when window gets destroyed ?????????????????? HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU); ?????????????????? if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL) ?????????????????? { ??????????????????????????? TRACE0("Warning: failed to load menu for CFrameWnd.\n"); ??????????????????????????? PostNcDestroy();??????????? // perhaps delete the C++ object ??????????????????????????? return FALSE; ?????????????????? } ???????? } ???????? m_strTitle = lpszWindowName;??? // save title for later ???????? if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, ?????????????????? rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, ?????????????????? pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext)) ???????? { ?????????????????? TRACE0("Warning: failed to create CFrameWnd.\n"); ?????????????????? if (hMenu != NULL) ??????????????????????????? DestroyMenu(hMenu); ?????????????????? return FALSE; ???????? } ???????? return TRUE; } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
3.???????CWnd:CreateEx (WINCORE.CPP)
| MFC\SRC\WINFRM.CPP: ? 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) { ???????? // allow modification of several common create parameters ???????? CREATESTRUCT cs; ???????? cs.dwExStyle = dwExStyle; ???????? …… ???????? if (!PreCreateWindow(cs)) //完成注冊窗口類工作 ???????? { ?????????????????? PostNcDestroy(); ?????????????????? return FALSE; ???????? } ? ???????? AfxHookWindowCreate(this); ???????? HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass, ??????????????????????????? cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, ??????????????????????????? cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams); ???????? …… } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
以下是CREATESTRUCT和CreateWindowEx參數(shù)的對比:
由于CREATESTRUCT中的屬性都定義為指針,故可在PreCreateWindow中更改屬性,在CreateWindowEx中將更改顯示。
?
4.????? MFC的調用關系
① theApp
| theApp(CMyFirstMFCApp.CPP) ——> CWinAPP ::CWinAPP(){ pModuleState->m_pCurrentWinApp = this; ?} ? | ? |
?
?
?
?
② _tWinMain(APPMODUL.CPP)
| _tWinMain () { AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } ? | ? |
?
?
?
?
?
?
?
??
③ AfxWinMain(WinMain.CPP)
| int AFXAPI AfxWinMain() { CWinThread* pThread = AfxGetThread(); //——>return AfxGetApp() (:THRDCORE.CPP) ???????? CWinApp* pApp = AfxGetApp(); //——>return afxCurrentWInApp (:AFXWIN1.INL) //——>return AfxGetModuleState()->m_pCurrentWinApp (:AFXWIN.H) AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow); pApp->InitApplication(); pThread-> InitInstance (); ???????? //——> CMyFirstMFCApp::InitInstance ?????????????????? //——> AddDocTemplate(pDocTemplate); ??????????????????????????? //——> m_pMainWnd->ShowWindow(SW_SHOW); ?????????????????? //——> m_pMainWnd->UpdateWindow(); pThread->Run(); } ? | ? |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
④ 窗口
設計和注冊窗口:
| CMainFrame::PreCreateWindow (\Project\ CMainFrame.cpp) ???????? ——>CFrameWnd::PreCreateWindow ?????????????????? ——>AfxDeferRegisterClass(宏= AfxEndDeferRegisterClass) ——>AfxEndDeferRegisterClass ——>AfxRegisterClass ???????? ——>::RegisterClass (SDK) ? | ? |
?
?
?
?
?
?
?
?
創(chuàng)建窗口:
CFrameWnd::Create()
???????? ——>CFrameWnd::CreateEx()
——>CWnd::CreateEx()
???????? ——>virsual CWnd::PreCreateWIndow(虛函數(shù),調用子類中CFrameWnd:: PreCreateWIndow),
:: CreateWIndowEx()
總結
以上是生活随笔為你收集整理的MFC封装API的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。