Module State保存着和Module相关的状态信息。Module是Windows的术语,代表任何一个可执行的代码文件, EXE和DLL都是Module的一种。Module State有下面几种:
1. AFX_MODULE_STATE,保存MODULE的信息,是_AFX_BASE_MODULE_STATE和_AFX_DLL_MODULE_STATE的基类
2. _AFX_BASE_MODULE_STATE,保存MFC Module的状态信息,没有定义其他的成员
3. _AFX_DLL_MODULE_STATE,保存DLL的状态信息,没有定义其他的成员
4. AFX_MODULE_THREAD_STATE,保存主线程的有关状态信息,虽然AFX_MODULE_THREAD_STATE是保存的线程的状态信息,但是它只保存Module的主线程的状态信息,所以可以看作是Module State的一种。
这些Module State保存了MFC中的大量重要信息:
1. CWinApp指针
2. 实例句柄
3. 资源Module的句柄
4. 句柄表
5. OLE相关信息
6. 窗口过程
7. Activation Context
8. ……
AFX_MODULE_STATE的定义如下:
// AFX_MODULE_STATE (global data for a module) class AFX_MODULE_STATE : public CNoTrackObject { public: #ifdef _AFXDLL AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion, BOOL bSystem = FALSE); #else explicit AFX_MODULE_STATE(BOOL bDLL); #endif ~AFX_MODULE_STATE();
CWinApp* m_pCurrentWinApp; HINSTANCE m_hCurrentInstanceHandle; HINSTANCE m_hCurrentResourceHandle; LPCTSTR m_lpszCurrentAppName; // …… 其他成员,从略 }; |
可以看到:
1. AFX_MODULE_STATE从CNoTrackObject继承。CNoTrackObject定义了自己的new/delete保证自己不会被各种调试版本的new/delete来Track,以免自己被错误的当作Leak。
2. AFX_MODULE_STATE在DLL和非DLL(也就是EXE)的情况下具有不同的构造函数(和成员)
3. AFX_MODULE_STATE在成员中保存了一些和Module相关的重要信息
实际上,AFX_MODULE_STATE并没有被直接使用,而是作为_AFX_BASE_MODULE_STATE和_AFX_DLL_MODULE_STATE的基类:
_AFX_BASE_MODULE_STATE被用于Module,其定义如下:
class _AFX_BASE_MODULE_STATE : public AFX_MODULE_STATE { public: #ifdef _AFXDLL _AFX_BASE_MODULE_STATE() : AFX_MODULE_STATE(TRUE, AfxWndProcBase, _MFC_VER) #else _AFX_BASE_MODULE_STATE() : AFX_MODULE_STATE(TRUE) #endif { } };
PROCESS_LOCAL(_AFX_BASE_MODULE_STATE, _afxBaseModuleState) |
_AFX_DLL_MODULE_STATE和_AFX_BASE_MODULE_STATE类似,只是仅用于DLL:
class _AFX_DLL_MODULE_STATE : public AFX_MODULE_STATE { public: _AFX_DLL_MODULE_STATE() : AFX_MODULE_STATE(TRUE, AfxWndProcDllStatic, _MFC_VER) { } };
static _AFX_DLL_MODULE_STATE afxModuleState; |
这两个class都没有定义额外的成员,比较简单,只是传入到基类AFX_MODULE_STATE的参数不同。此外,他们定义的方式不太一样,前者使用的是PROCESS_LOCAL宏,定义了一个变量_afxBaseModuleState。后者只是简单的定义了一个static变量afxModuleState。
下面这些函数可以用来获得Module的State:
1. AfxGetModuleState
AfxGetModuleState首先获得_afxThreadState的m_pModuleState,如果当前的Thread State的m_pModuleState返回NULL,说明当前的Thread State没有正确的初始化(通常的原因是创建线程的时候调用的是CreateThread函数而非AfxBeginThread),则使用_afxBaseModuleState。
AFX_MODULE_STATE* AFXAPI AfxGetModuleState() { _AFX_THREAD_STATE* pState = _afxThreadState; ENSURE(pState); AFX_MODULE_STATE* pResult; if (pState->m_pModuleState != NULL) { // thread state's module state serves as override pResult = pState->m_pModuleState; } else { // otherwise, use global app state pResult = _afxBaseModuleState.GetData(); } ENSURE(pResult != NULL); return pResult; } |
_afxBaseModuleState是用PROCESS_LOCAL定义的:
PROCESS_LOCAL(_AFX_BASE_MODULE_STATE, _afxBaseModuleState) |
它代表整个MFC Module的State。当你的程序是动态链接到MFC DLL的时候,该State只有一份。如果你的程序是静态链接到MFC的话,有几个模块(EXE/DLL)静态链接到MFC,MFC的代码就有几份,那么_afxBaseModuleState也就有几份。
2. AfxGetStaticModuleState
AfxGetStaticModuleState在不同的Project下面有着不同的行为:在DLL项目中,AfxGetSaticModuleState返回afxModuleState,也就是定义好的_AFX_DLL_MODULE_STATE,而在非DLL项目中,AfxGetStaticModuleState直接调用AfxGetModuleState。可以看到,在DLL的情况下,必须使用AfxGetStaticModuleState才可以获得DLL本身的Module State。
#ifdef _AFXDLL
static _AFX_DLL_MODULE_STATE afxModuleState;
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = &afxModuleState; return pModuleState; }
#else
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); return pModuleState; } #endif |
3. AfxGetAppModuleState
AfxGetAppModuleState是最简单的,直接返回_afxBaseModuleState:
AFX_MODULE_STATE* AFXAPI AfxGetAppModuleState() { return _afxBaseModuleState.GetData(); } |
从上面的讨论可以看出,当前处于那个MFC Module的状态之中,返回的就是那个MFC Module所相关联的CWinApp对象。如果你有多个Module都是动态链接到MFC DLL的话,那么AfxGetAppModuleState返回的总是同一个CWinApp。
ily: 宋体; mso-fareast-theme-font: minor-fareast">_afxBaseModuleState也就有几份。
2. AfxGetStaticModuleState
AfxGetStaticModuleState在不同的Project下面有着不同的行为:在DLL项目中,AfxGetSaticModuleState返回afxModuleState,也就是定义好的_AFX_DLL_MODULE_STATE,而在非DLL项目中,AfxGetStaticModuleState直接调用AfxGetModuleState。可以看到,在DLL的情况下,必须使用AfxGetStaticModuleState才可以获得DLL本身的Module State。
#ifdef _AFXDLL
static _AFX_DLL_MODULE_STATE afxModuleState;
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = &afxModuleState; return pModuleState; }
#else
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); return pModuleState; } #endif |
3. AfxGetAppModuleState
AfxGetAppModuleState是最简单的,直接返回_afxBaseModuleState:
AFX_MODULE_STATE* AFXAPI AfxGetAppModuleState() { return _afxBaseModuleState.GetData(); } |
从上面的讨论可以看出,当前处于那个MFC Module的状态之中,返回的就是那个MFC Module所相关联的CWinApp对象。如果你有多个Module都是动态链接到MFC DLL的话,那么AfxGetAppModuleState返回的总是同一个CWinApp。
ily: 宋体; mso-fareast-theme-font: minor-fareast">_afxBaseModuleState也就有几份。
2. AfxGetStaticModuleState
AfxGetStaticModuleState在不同的Project下面有着不同的行为:在DLL项目中,AfxGetSaticModuleState返回afxModuleState,也就是定义好的_AFX_DLL_MODULE_STATE,而在非DLL项目中,AfxGetStaticModuleState直接调用AfxGetModuleState。可以看到,在DLL的情况下,必须使用AfxGetStaticModuleState才可以获得DLL本身的Module State。
#ifdef _AFXDLL
static _AFX_DLL_MODULE_STATE afxModuleState;
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = &afxModuleState; return pModuleState; }
#else
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); return pModuleState; } #endif |
3. AfxGetAppModuleState
AfxGetAppModuleState是最简单的,直接返回_afxBaseModuleState:
AFX_MODULE_STATE* AFXAPI AfxGetAppModuleState() { return _afxBaseModuleState.GetData(); } |
从上面的讨论可以看出,当前处于那个MFC Module的状态之中,返回的就是那个MFC Module所相关联的CWinApp对象。如果你有多个Module都是动态链接到MFC DLL的话,那么AfxGetAppModuleState返回的总是同一个CWinApp。
ily: 宋体; mso-fareast-theme-font: minor-fareast">_afxBaseModuleState也就有几份。
2. AfxGetStaticModuleState
AfxGetStaticModuleState在不同的Project下面有着不同的行为:在DLL项目中,AfxGetSaticModuleState返回afxModuleState,也就是定义好的_AFX_DLL_MODULE_STATE,而在非DLL项目中,AfxGetStaticModuleState直接调用AfxGetModuleState。可以看到,在DLL的情况下,必须使用AfxGetStaticModuleState才可以获得DLL本身的Module State。
#ifdef _AFXDLL
static _AFX_DLL_MODULE_STATE afxModuleState;
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = &afxModuleState; return pModuleState; }
#else
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState() { AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); return pModuleState; } #endif |
3. AfxGetAppModuleState
AfxGetAppModuleState是最简单的,直接返回_afxBaseModuleState:
AFX_MODULE_STATE* AFXAPI AfxGetAppModuleState() { return _afxBaseModuleState.GetData(); } |
从上面的讨论可以看出,当前处于那个MFC Module的状态之中,返回的就是那个MFC Module所相关联的CWinApp对象。如果你有多个Module都是动态链接到MFC DLL的话,那么AfxGetAppModuleState返回的总是同一个CWinApp。