<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    MFC全局函數開局――AfxGetApp解剖

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    MFC中有不少的全局函數,方便在不同對象中獲取不同的內容或創建不同的對象。主要全局函數有:

    AfxWinInit() AfxBeginThread() AfxEndThread() AfxFormatString1() AfxFormatString2()

    AfxMessageBox()   AfxOutPutDebugString()   AfxGetApp() AfxGetMainWnd() AfxGetInstance()

    AfxRegisterClass()

    這些函數從名稱上可見豹斑(功能)。

    本文是學習深入淺出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的指針的原因了。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全