一个MFC程序启动机制。
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); aaa//当前程序模块信息
class AFX_MODULE_STATE : public CNoTrackObject
#ifdef _AFXDLL
#define _AFX_CMDTARGET_GETSTATE() (m_pModuleState)
#else
#define _AFX_CMDTARGET_GETSTATE() (AfxGetModuleState())
#endif
CMyWinApp theApp{
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();//获取全局变量模块状态aaa
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;//获取全局变量线程状态信息bbb
pThreadState->m_pCurrentWinThread = this; //将theApp地址赋值给aaa对象
}
CWinThread* AFXAPI AfxGetThread()
{
// check for current thread in module thread state
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
//以Afx开头的都是全局的获取全局变量BBB的地址
CWinThread* pThread = pState->m_pCurrentWinThread;
//CMyWinApp-->CWinApp-->CWinThread-->CCmdTarget-->CObject
//基类指针指向孙子类
// if no CWinThread for the module, then use the global app
if (pThread == NULL)
pThread = AfxGetApp();
return pThread;
}
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp() //获取全局对象
{ return afxCurrentWinApp; }
#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
pThreadModule->m_pCurrentWinThread=this
MFC第一大机制
MFC程序启动机制
第一个MFC程序
环境配置:
删除WinMain函数
将包含的头文件改为<afxwin.h>
project->Settings中使用MFC库
代码编写
从CFrameWnd类派生自己的子类CMyFrameWnd
从CWinApp类派生自己的子类CMtWinApp
在CMyWinApp类内部重写父类的成员虚函数IninInstance
全局域中定义一个全局对象CMyWinApp theApp(爆破点)
程序执行过程:
1.mfc封装WinMain所以程序不需要实现
2.构造theApp全局对象,执行CWinApp类的构造函数
1)将theApp对象地址保存到当前程序模块状态信息中
2)将theApp对象地址保存到当前程序线程状态信息中
3)AfxGetThread/AfxGetApp --返回theApp对象地址
3.进入WinMain函数,其直接调用AfxWinMain函数
1)AfxWinMain执行过程
1)获取theApp地址
2)利用theApp对象地址调用InitApplication虚函数初始化MFC应用程序
3)利用theApp对象地址调用InitInstance虚函数,创建、显示、刷新 窗口
4)利用theApp对象设置调用Run虚函数,实现消息循环
5)程序退出时利用theApp对象地址调用ExiyInstance虚函数,善后处理。
应用程序类(CWinApp)
成员虚函数
InitApplication
InitInstance
OnIdel
Run
ExitInstance
成员变量
m_pMainWnd
theApp
--->m_pMainWnd
MFC类库中没有对象,只有类
**********************************************************************
WinMain(...){
AfxWinMain(....){
CWinThread* pThread = AfxGetThread(); ////theApp地址
CWinApp* pApp = AfxGetApp(); ////theApp地址
//以上两句获取theApp对象地址
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
//初始化MFC库
pApp->InitApplication() //theApp-->虚函数
//重写后执行流程会改变,执行自己的函数
//实为CWinApp的
pThread->InitInstance() //回到自己写的代码 重写改变执行流程
//this指针为theApp对象地址.pThread值为theApp
//InitInstance由pThread调用
nReturnCode = pThread->Run();{ //this==pThread==theApp还是theApp
CWinThread::Run();{ //函数内部this指针为theApp地址
while(没有消息){
空闲处理
ths->OnIdel(); //空闲处理
}
PumpMessage(){ pump 打气筒,抽取
if(GetMessage抓到WM_QUIT){
return FALSE;
}
}
if(PumpMessage返回FALSE){
ExitInstance();//应用程序类的虚函数,善后处理
}
}
}
}
}
一直由theApp对象指针调用虚函数
***************************************************************************
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance(){ //this======theApp
CMyFrameWnd *pFrame=new CMyFrameWnd(); //框架类对象
pFrame->Create(NULL,"MyFrame"); //创建+注册
m_pMainWnd=pFrame; //this->m_pMainWnd保存框架类对象地址
pFrame->ShowWindow(SW_SHOW); //目测为CWinApp类的成员
pFrame->UpdateWindow(); //成员函数由theApp调用
return TRUE;
}
int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation, but has no main window!
TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
AfxPostQuitMessage(0); //退出程序
}
return CWinThread::Run(); this->CWinAppThread::Run();
}
BOOL CWinThread::PumpMessage()
{
ASSERT_VALID(this);
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
#ifdef _DEBUG
if (afxTraceFlags & traceAppMsg)
TRACE0("CWinThread::PumpMessage - Received WM_QUIT.\n");
m_nDisablePumpCount++; // application must die
// Note: prevents calling message loop things in 'ExitInstance'
// will never be decremented
#endif
return FALSE;
}
#ifdef _DEBUG
if (m_nDisablePumpCount != 0)
{
TRACE0("Error: CWinThread::PumpMessage called when not permitted.\n");
ASSERT(FALSE);
}
#endif
#ifdef _DEBUG
if (afxTraceFlags & traceAppMsg)
_AfxTraceMsg(_T("PumpMessage"), &m_msgCur);
#endif
// process this message
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
}
return TRUE;
}
int CWinThread::Run()
{
ASSERT_VALID(this);
// 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(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) //没消息时
//进入while循环
//::表示win32函数
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
//this->OnIdel(空闲次数) OnIdel()前没有::,是成员函数
bIdle = FALSE; // assume "no idle" state
}
// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance(); //this->ExitInstance() theApp
//应用程序类的成员虚函数
//点击关闭按钮出发的事件
// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
ASSERT(FALSE); // not reachable
}
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread(); ////theApp地址
CWinApp* pApp = AfxGetApp(); ////theApp地址
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) //初始化MFC库
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE0("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)
{
TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}原文:http://blog.csdn.net/u011185633/article/details/44775705