学MFC,竟然还不知道MFC的MAIN函数在什么地方?怎么运行的?实在不高明。于是决定模仿JJHOU老师的方式,拿起手术刀,深入MFC的内部运行机制。但是俗话说,循序渐进。就是说在我们深入之前,首先要浅析一下… …
假如你用AppWizard一步一步NEXT下来,然后在CLASSVIEW中去找寻WINMAIN函数,那么你只有失望。MFC最大的特点是什么?封装!MFC的确封装的太好了,以至于很多想学习MFC的人都望而却步。闲话少说,还是继续我们今天的话题,MAIN函数!实话告诉你吧,即使你搜索所有的MFC生成的文件,都无法发现WINMAIN的字眼,那么它就近在什么地方呢?
我相信你已经想到,MAIN函数应该在主要的应用程序文件中。难道是“您定义的程序名.cpp”这个文件?不错就是它。再Crtl+F一下,看有没有我们要找的WINMAIN函数?看来你又要失望了,但是你主意有这样一句:
/
// The one and only CMy1App object
CMy1App theApp; //本人建立的工程名为1。
是不是很特别,再注意一下那句注释“The one and only CMy1App object”,每个应用程序有且只用一个CMy1App对象。我想你应该想到了,WinMain函数每个程序也只能有一个,那么这个全局对象跟WinMain函数肯定有莫大的关系?没错,相信你的直觉。
现在,我们该深入WinMain运行机制了。
首先,看看MFC的库文件把,它能给我们带来许多惊喜。(vc6的相应的目录是/Microsoft Visual Studio/VC98/MFC/SRC;VC7相应的目录是/Microsoft Visual Studio .NET 2003/Vc7/atlmfc/src/mfc)
首先应该看看CMy1App的基类,CWinApp的构造函数(在APPCORE.CPP中),找到以下内容:
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;
ASSERT(AfxGetApp() == this);
... ...
}
OK,就到这里就可以了。现在请注意:
pModuleState->m_pCurrentWinApp = this;
这段代码的意思是,获得了CWinApp的全局对象的this指针。CWinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置和初始值。theApp配置完成以后,接下来就是今天的主角儿了,WinMain函数,打开appmodul.cpp:
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
然后再打开winmain.cpp:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE(traceAppMsg,0,"Warning:Destroying non-NULL m_pMainWnd/n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
终于看到WinMain的真面目了,但是我们并不能满足,接下来,我们要了解他的运行机制,我们要知其然,更要知其所以然。只知其然,实在不高明!