MFC程序的执行顺序

简介
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函数).

猜你喜欢

转载自blog.csdn.net/a906168402/article/details/70847017