简介
MFC只是对WIN32的API进行了封装,所以MFC的本质还是WIN32程序.有了这层封装,我们看不到WIN32的WinMain函数,也就不清楚MFC程序的启动过程.虽然我们没有看到WinMain函数,但不代表没有WinMain函数,这个函数位于*\VC\atlmfc\src\mfc目录的appmodul .cpp文件中有一个_tWinMain函数, _tWinMain函数调用了WinMain.CPP文件中的AfxWinMain函数.
_tWinMain函数实现:
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
__in LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
AfxWinMain函数实现:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
__in 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;
}
nReturnCode = pThread->Run();
InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
_tWinMain和WinMain的声明是一致的,但是_tWinMain不是最先执行的,因为整个程序一开始是初始化全局变量,这里的全局变量有WinApp类型的theApp,初始化theApp就是执行CWinApp的构造函数.在这个AfxWinMain函数里面调用了pThread->InitInstance()函数,InitInstance函数是CWinApp类(CWinApp继承于CWinThread)的虚函数,所以这里就调用派生类的InitInstance函数,用户一般在这个函数里面创建对话框,单文档,多文档界面。执行完InitInstance函数后,就会执行CWinApp类的run函数(*\VC\atlmfc\src\mfc\thrdcore.cpp),这个函数一个死循环,不断地从的消息队列中读取消息.代码如下:
int CWinThread::Run()
{
ASSERT_VALID(this);
_AFX_THREAD_STATE* pState = AfxGetThreadState();
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
}
// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance();
// reset "no idle" state after pumping "normal" message
//if (IsIdleMessage(&m_msgCur))
if (IsIdleMessage(&(pState->m_msgCur)))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));
}
}
小结
MFC程序的执行顺序和Win32的执行顺序完全一样:初始化全局变量(theApp),执行WinMain函数(AfxWinMain),创建及注册窗口(在InitInstance函数中创建对话框,单文档,多文档窗口),消息循环(Run函数).