4.探索AfxWinMain
在WinMain函数的定义中可以发现仅有一行:
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
所以WinMain的具体实现是交给AfxWinMain完成的。
打开WinMain.cpp查看定义:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine, int nCmdShow)
{ASSERT(hPrevInstance == NULL);int nReturnCode = -1;CWinThread* pThread = AfxGetThread(); //CWinApp派生于CWinThreadCWinApp* pApp = AfxGetApp(); //CTestApp派生于CWinApp// AFX internal initializationif (!AfxWinInit(hInstance, hPrevInstance,lpCmdLine, nCmdShow))goto InitFailure;// App global initializations (rare)if (pApp != NULL &&!pApp->InitApplication()) //初始化应用程序,完成MFC内部初始化管理方面的工作goto InitFailure;// Perform specific initializationsif (!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;}nReturnCode = pThread->Run(); //run方法,与消息循环有关InitFailure:
#ifdef _DEBUG// Check for missing AfxLockTempMap callsif(AfxGetModuleThreadState()->m_nTempMapLock != 0){TRACE(traceAppMsg, 0,"Warning: Temp map lock count non-zero (%ld).\n",AfxGetModuleThreadState()->m_nTempMapLock);}AfxLockTempMaps();AfxUnlockTempMaps(-1);
#endifAfxWinTerm();return nReturnCode;
}
关键行1:CWinThread* pThread =AfxGetThread();
我们转到AfxGetThread函数的定义,位于THREDCORE.CPP文件中。
CWinThread* AFXAPI AfxGetThread()
{// check for current thread in modulethread stateAFX_MODULE_THREAD_STATE* pState =AfxGetModuleThreadState();CWinThread* pThread =pState->m_pCurrentWinThread;return pThread;
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------
发现与书中相比少了如下几行:
//if no CWinThreadfor the module, then use the global app.if(pThread == NULL)pThread = AfxGetApp();
根据MSDN2013对于AfxGetThread的批注:
If you are porting an MFC project calling AfxGetThread fromVisual C++ versions 4.2, 5.0, or 6.0,AfxGetThread calls AfxGetApp if no thread is found. In VisualC+ .NET and later,AfxGetThread returnsNULL if nothread was found. If you want the application thread, you must call AfxGetApp.
翻译:
如果你正在移植一个MFC项目,并且是从旧版本的VC++(如VC++6.0)调用AfxGetThread函数,那么AfxGetThread调用AfxGetApp如果没有找到线程。(如上面的代码:pThread=AfxGetApp(); )在之后的VC版本中,如果没有找到线程,那么这个函数返回值是NULL。如果你想要获得应用程序线程,必须调用AfxGetApp。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
关键行2:CWinAPP* pApp =AfxGetApp ();
查看AfxGetApp定义:位于AFXWIN1.INL
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp(){ return afxCurrentWinApp; }
查看afxCurrentWinApp的定义:位于AFXWIN.H
#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
根据前面CWinApp构造函数的定义,m_pCurrentWinApp存放的就是theApp对象。
也就是说,对于Test程序,pApp指向的是theApp这个全局对象。
但是调用了AfxGetApp函数也没有明白pThread指针指向哪里,书中是在pThread为NULL时让pThread = AfxGetApp();,而现在没有这行赋值语句?
这里我的猜想是pThread会在调用其他函数的时候来得到应用程序线程(Test应用程序只有一个线程,多线程的问题以后再研究),因为pThread->InitInstance(),pThread->ExitIn