日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC封装API

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC封装API 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Win32Application Architecture

一個Win32 Application Architecture的代碼結構如下:

LRESULT CALLBACK WinWordsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);? //定義回調處理消息函數

?

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){

???????? // 創建一個窗口類分為三步:1.設計窗口類 2.注冊窗口類 3.創建窗口 4.顯示及更新窗口

???????? // 步驟1.設計窗口類

???????? WNDCLASS wc;

……

???????? // 步驟2:注冊窗口類

???????? RegisterClass(&wc);

???????? // 步驟3:創建窗口

???????? 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);

???????? // 消息循環

???????? 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程序入口,并開始執行

2.???????創建并設計窗口類

3.???????注冊窗口類

4.???????創建窗口

5.???????顯示及更新窗口

6.???????循環獲取消息,經處理,交還系統讓其調用相關回調消息處理函數進行處理。

?

二、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,體現“文檔/視圖”結構。其項目結構如下所示:

?

2.????? MFC的執行過程

對于MFC框架運行過程進行剖析,最好的資料是MFC源代碼,VC6位于“\Microsoft Visual Studio\VC98\MFC\SRC”下。執行過程如下:

定義theApp(:CMyFistMFCApp)

?????????????????? ——>執行構造函數:CWinApp()->CMyFistMFCApp()->

???????????????????????????????????? ——>程序入口_tWinMain (宏,定義為WInMain)

——>執行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函數的宏,定義如下:

?

#define _tmain????? main

#define _tWinMain?? WinMain

#ifdef? _POSIX_

#define _tenviron?? environ

?

?
?

?

?

?


由此可見,WinMain中調用AfxWinMain進行處理。MFC包含此文件,故將找到此入口并自動調用執行。

?

2.2? theApp全局對象

在Project\CMyFirstMFCApp.CPP中,可找到一行代碼發下:

Project\CMyFirstMFCApp.CPP:

?

/

// The one and only CMyFistMFCApp object

CMyFistMFCApp theApp;

?

?
?

?

?

?

?


當定義theApp時,將先執行CWinApp(\MFC\SRC\APPCORE.CPP)的構造函數:

\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構造函數時初始化為this的m_pCurrentWinApp。

?

4.InitInstance

類CWinAPP(APPCORE.CPP)中InitInstance函數定義為:

\MFC\SRC\ APPCORE.CPP:

?

// overrides for implementation

virtual BOOL InitInstance();

?

?
?

?

?

?


類InitInstance即為虛函數,根據多態性,將調用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函數來處理回調消息。 (!~)

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 創建窗口

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參數的對比:


由于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)

?

?
?

?

?

?

?

?

?

?


創建窗口:

CFrameWnd::Create()

???????? ——>CFrameWnd::CreateEx()

——>CWnd::CreateEx()

???????? ——>virsual CWnd::PreCreateWIndow(虛函數,調用子類中CFrameWnd:: PreCreateWIndow),

:: CreateWIndowEx()

總結

以上是生活随笔為你收集整理的MFC封装API的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。