MFC的入口函数(main函数)

其实想看MFC的main函数,打开任一用MFC开发的App,设一个断点,然后查看调用堆栈。拉到最底部(即最先开始调用的东西)

在appmodul.cpp中可以看到如下代码:

// This is a part of the Microsoft Foundation Classes C++ library.

// Copyright (C) Microsoft Corporation

// All rights reserved.

//

// This source code is only intended as a supplement to the

// Microsoft Foundation Classes Reference and related

// electronic documentation provided with the library.

// See these sources for detailed information regarding the

// Microsoft Foundation Classes product.

#include "stdafx.h"

#include "sal.h"

/

// export WinMain to force linkage to this module

extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

_In_ LPTSTR lpCmdLine, int nCmdShow);

extern "C" int WINAPI

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

_In_ LPTSTR lpCmdLine, int nCmdShow)

#pragma warning(suppress: 4985)

{

// call shared/exported WinMain

return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

可以看到,转入了AfxWinMain,继续跟

在winmain.cpp中可以看到

// This is a part of the Microsoft Foundation Classes C++ library.

// Copyright (C) Microsoft Corporation

// All rights reserved.

//

// This source code is only intended as a supplement to the

// Microsoft Foundation Classes Reference and related

// electronic documentation provided with the library.

// See these sources for detailed information regarding the

// Microsoft Foundation Classes product.

#include "stdafx.h"

#include "sal.h"

/

// Standard WinMain implementation

// Can be replaced as long as 'AfxWinInit' is called first

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;

}

/

可以看到,在这里面先对窗口进行了初始化,再对线程和app对象进行了初始化,即依次对三个函数的调用:

AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

pApp->InitApplication();

pThread->InitInstance();

一个个看:

AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow):

在appinit.cpp中:

// This is a part of the Microsoft Foundation Classes C++ library.

// Copyright (C) Microsoft Corporation

// All rights reserved.

//

// This source code is only intended as a supplement to the

// Microsoft Foundation Classes Reference and related

// electronic documentation provided with the library.

// See these sources for detailed information regarding the

// Microsoft Foundation Classes product.

#include "stdafx.h"

#ifdef _AFXDLL

#include "afxglobals.h"

#endif

#include "sal.h"

/

BOOL AFXAPI AfxWinInit(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,

_In_z_ LPTSTR lpCmdLine, _In_ int nCmdShow)

{

ASSERT(hPrevInstance == NULL);

// handle critical errors and avoid Windows message boxes

SetErrorMode(SetErrorMode(0) |

SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);

// set resource handles

AFX_MODULE_STATE* pModuleState = AfxGetModuleState();

pModuleState->m_hCurrentInstanceHandle = hInstance;

pModuleState->m_hCurrentResourceHandle = hInstance;

// fill in the initial state for the application

CWinApp* pApp = AfxGetApp();

if (pApp != NULL)

{

// Windows specific initialization (not done if no CWinApp)

pApp->m_hInstance = hInstance;

hPrevInstance; // Obsolete.

pApp->m_lpCmdLine = lpCmdLine;

pApp->m_nCmdShow = nCmdShow;

pApp->SetCurrentHandles();

}

// initialize thread specific data (for main thread)

if (!afxContextIsDLL)

AfxInitThread();

return TRUE;

}

pApp->InitApplication():

在appcore.cpp中:

BOOL CWinApp::InitApplication()

{

if (CDocManager::pStaticDocManager != NULL)

{

if (m_pDocManager == NULL)

m_pDocManager = CDocManager::pStaticDocManager;

CDocManager::pStaticDocManager = NULL;

}

if (m_pDocManager != NULL)

m_pDocManager->AddDocTemplate(NULL);

else

CDocManager::bStaticInit = FALSE;

LoadSysPolicies();

return TRUE;

}

pThread->InitInstance():

在thrdcore.cpp中:

/

// CWinThread default implementation

BOOL CWinThread::InitInstance()

{

ASSERT_VALID(this);

return FALSE; // by default don't enter run loop

}

CWinThread::Run():

// main running routine until thread exits

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));

}

}

可以看到在CWinThread::Run()进入了消息循环,直到收到WM_QUIT消息,退出消息循环。

最后看看AfxWinTerm():

在appterm.cpp中:

void AFXAPI AfxWinTerm(void)

{

AfxUnregisterWndClasses();

// cleanup OLE if required

CWinThread* pThread = AfxGetApp();

if (pThread != NULL && pThread->m_lpfnOleTermOrFreeLib != NULL)

(*pThread->m_lpfnOleTermOrFreeLib)(TRUE, FALSE);

// cleanup thread local tooltip window

AFX_MODULE_THREAD_STATE* pModuleThreadState = AfxGetModuleThreadState();

if (pModuleThreadState->m_pToolTip != NULL)

{

if (pModuleThreadState->m_pToolTip->DestroyToolTipCtrl())

pModuleThreadState->m_pToolTip = NULL;

}

_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();

if (!afxContextIsDLL)

{

// unhook windows hooks

if (pThreadState->m_hHookOldMsgFilter != NULL)

{

::UnhookWindowsHookEx(pThreadState->m_hHookOldMsgFilter);

pThreadState->m_hHookOldMsgFilter = NULL;

}

if (pThreadState->m_hHookOldCbtFilter != NULL)

{

::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter);

pThreadState->m_hHookOldCbtFilter = NULL;

}

}

// We used to suppress all exceptions here. But that's the wrong thing

// to do. If this process crashes, we should allow Windows to crash

// the process and invoke watson.

}

Remark:

MFC的代码是可以一步步跟的,一步步看。

大致的基础流程就是上述代码,这篇权当抛砖引玉,需要深入学习MFC的框架还有很多要学习的。

小菜鸟一枚,与大家共同学习。


盛开的花朵简笔画
搞机吧 | 利用magisk安装Xposed框架