AfxGetApp()解析

來源:互聯網
上載者:User

。解析AfxGetApp()函數

本文是學習深入淺出MFC後的第一個筆記,解析AfxGetApp()函數

在AFXWIN.H中是這麼定義的:

    CWinApp* AFXAPI AfxGetApp();

那麼AfxGetApp是怎麼擷取當前App的CWinApp類指標呢?

AfxGetApp是一個內嵌函式,其實現如下(在AFXWIN1.INL):

     _AFXWIN_INLINE CWinApp *AFXAPI AfxGetApp()

              { return afxCurrentWinApp;}

而afxCurrentWinApp是一個宏,定義在AFXWIN.H中:

     #define afxCurrentWinApp    AfxGetModuleState()->m_pCurrentWinApp

AfxGetModuleState返回的是一個:AFX_MODULE_STATE類的指標(AFXSTAT_.H):

     AFX_MODULE_STATE* AFXAPI AfxGetModuleState();

在AFX_MODULE_STATE類中定義了如下的成員變數:

     CWinApp* m_pCurrentWinApp;
      HINSTANCE m_hCurrentInstanceHandle;
     HINSTANCE m_hCurrentResourceHandle;
      LPCTSTR m_lpszCurrentAppName;
      BYTE m_bDLL;    // TRUE if module is a DLL, FALSE if it is an EXE
      BYTE m_bSystem; // TRUE if module is a "system" module, FALSE if not
      BYTE m_bReserved[2]; // padding
      DWORD m_fRegisteredClasses; // flags for registered window classes

轉了這麼多,自己都迷糊了,AFX_MODULE_STATE什麼時候被初始化了,AfxGetModuleState又都幹了些什麼,不然怎麼可能調用AfxGetModuleState()->m_pCurrentWinApp獲得當前視窗的App呢?最有可能被初始化的地方是在建構函式 之中。而我們擷取的是App類型的指標,而App是繼承之CWinApp類的。因此下面我們看看CWinApp建構函式做了些什麼工作:

CWinApp::CWinApp(LPCTSTR lpszAppName)
{
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;     //又將this指標傳給了m_pCurrentWinApp,哦呵呵……
ASSERT(AfxGetApp() == this);

// in non-running state until WinMain
m_hInstance = NULL;
m_pszHelpFilePath = NULL;
m_pszProfileName = NULL;
m_pszRegistryKey = NULL;
m_pszExeName = NULL;
m_pRecentFileList = NULL;
m_pDocManager = NULL;
m_atomApp = m_atomSystemTopic = NULL;
m_lpCmdLine = NULL;
m_pCmdInfo = NULL;

// initialize wait cursor state
m_nWaitCursorCount = 0;
m_hcurWaitCursorRestore = NULL;

// initialize current printer state
m_hDevMode = NULL;
m_hDevNames = NULL;
m_nNumPreviewPages = 0;     // not specified (defaults to 1)

// initialize DAO state
m_lpfnDaoTerm = NULL;   // will be set if AfxDaoInit called

// other initialization
m_bHelpMode = FALSE;
m_nSafetyPoolSize = 512;        // default size
}

CWinApp的建構函式申明了一個AFX_MODULE_STATE類的指標,裡面通過this指標填充了AFX_MODULE_STATE指標中的部分內容。下面我們再來看看CWinApp中的_AFX_CMDTARGET_GETSTATE()又是什麼:

#ifdef _AFXDLL
#define _AFX_CMDTARGET_GETSTATE() (m_pModuleState)
#else
#define _AFX_CMDTARGET_GETSTATE() (AfxGetModuleState())
#endif

如果此處不考慮_AFXDLL情況,那麼在CWinApp中將直接調用 AfxGetModuleState()函數,瞧,又是AfxGetModuleState()函數。於是我們可以這麼考慮,在記憶體中有一份全域或靜態 AFX_MODULE_STATE類,AfxGetModuleState只是返回這一份全域指標(猜測)。在CWinApp中通過對AFX_MODULE_STATE中的m_pCurrentWinApp填充this指標後,將使全域的AFX_MODULE_STATE儲存當前WinApp中的CWinApp指標。

其中的特殊指之處在於使用了this指標,當基類被繼承後,this指標將代表繼承類的this指標。因此任何一個CWinApp被繼承後,如繼承類為CMyWinApp,那麼CMyWinApp的地址將被存在AFX_MODULE_STATE的全域變數之中,當使用AfxGetModuleState()函數擷取 AFX_MODULE_STATE時便可擷取當前系統的CMyWinApp指標m_pCurrentWinApp。

下面總結一下:

    當前指標通過AfxGetApp()通過返回afxCurrentWinApp,而afxCurrentWinApp宏為AfxGetModule()- >m_pCurrentWinApp,即AfxGetApp()通過返回AfxGetModule()->m_pCurrentWinApp 擷取當前App的指標,而AfxGetModule()->m_pCurrentWinApp指標通過CWinAPP建構函式通過this指標設 置,而this指標恰恰就是當前App的指標(this將轉換為繼承類的指標)。

    因此也就解釋了不管當前App被怎麼繼承,AfxGetModule()->m_pCurrentWinApp始終能夠擷取當前App的指標的原因了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.