MFC封装API

来源:互联网 发布:手机屏幕录视频软件 编辑:程序博客网 时间:2024/05/22 06:14

一、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()

0 0
原创粉丝点击