MFC的脉络
1. 新建一个MFC工程,名为:xuemaxiongfeng 生成一个类: CxuemaxiongfengApp 每个应用程序有且只用一个CxxxApp对象 WinMain函数每个程序也只能有一个,这个全局对象跟WinMain函数有莫大的关系2.全局对象优先于MIAN函数执行,且构建于栈中,切记,切记3.WinMain运行机制 (1)CxxxApp theApp; 统会执行CxxxApp的父类(CWinApp)构造函数,再执行CxxxApp的构造函数。 CWinApp的构造函数(在APPCORE.CPP中): CWinApp::CWinApp(LPCTSTR lpszAppName)
{
if (lpszAppName != NULL) //指定应用程序的名字,分配字符串lpszAppName长度的内存,然后返回地址指针赋给m_pszAppName
m_pszAppName = _tcsdup(lpszAppName);
else
m_pszAppName = NULL;
// initialize CWinThread state //用来管理模块(EXE/DLL文件)和线程状态数据的。Call this macro to protect an exported function in a DLL //AFX_MANAGE_STATE的作用切换到指定的Module State,当出了作用域的时候将Module State恢复到原来的值
//module 就是一个 PE文件,如:模块名称、模块基址、资源地址、是否DLL,是否系统模块,还有主线程对象,导入dll链 //表,OLE控制信息等
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); //线程状态信息,即模块线程的初始信息
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
ASSERT(AfxGetThread() == NULL); //一个单文档的MFC程序通过构造一个全局对象,将应用程序的实例对象传递给它的基类CWinApp //this指针代表的是应用程序的实例对象,参考this指针用法
pThreadState->m_pCurrentWinThread = this; //AfxGetThread()返回的是当前界面线程对象的指针
ASSERT(AfxGetThread() == this); //返回当前线程的虚拟句柄
m_hThread = ::GetCurrentThread(); //返回当前线程 ID
m_nThreadID = ::GetCurrentThreadId();
// initialize CWinApp state //afxCurrentWinApp是一个宏,#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
pModuleState->m_pCurrentWinApp = this; //AfxGetApp()返回的是应用程序对象的指针
ASSERT(AfxGetApp() == this);
// in non-running state until WinMain
m_hInstance = NULL; //标识应用程序的当前实例。
m_pszHelpFilePath = NULL; //应用程序的帮助文件的路径。
m_pszProfileName = NULL; //应用程序的 .INI 文件名。
m_pszRegistryKey = NULL; //用于确定存储应用程序配置文件设置完整的注册表项
m_pszExeName = NULL; //应用程序的模块名称
m_pRecentFileList = NULL; //
m_pDocManager = NULL; //
m_atomApp = m_atomSystemTopic = NULL; //
m_lpCmdLine = NULL; //指向指定应用程序的命令行以 NULL 结尾的字符串。
m_pCmdInfo = NULL; //
// initialize wait cursor state
m_nWaitCursorCount = 0; //
m_hcurWaitCursorRestore = NULL; //
// initialize current printer state
m_hDevMode = NULL; //
m_hDevNames = NULL; //
m_nNumPreviewPages = 0; // not specified (defaults to 1)
// initialize DAO state
m_lpfnDaoTerm = NULL; // will be set if AfxDaoInit called
// other initialization
m_bHelpMode = FALSE; //
m_nSafetyPoolSize = 512; // default size
} CWinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置和初始值
CWinApp封装用于 Windows 操作系统的应用程序的初始化、运行和终止
CWinApp 是从 CWinThread 派生的,后者表示可能具有一个或多个线程的应用程序的主执行线程。
创建一个应用程序对象,为对象创建一个线程,并设置线程的初始信息,最后返回应用程序对象指针
(2)关键字“WinMain”
参考《MFC自动调用Appmodul.cpp》http://www.cnblogs.com/xuemaxiongfeng/articles/2467958.html
(3)AfxWinMain
在WINMAIN.CPP中
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
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)
{
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;
}
MFC状态信息,包括模块,进程,线程状态信息。
具体可以查看
AFX_MODULE_PROCESS_STATE
AFX_MODULE_STATE
AFX_THREAD_STATE 派生类的内存模型是,先构造基类然后构造派生类。而派生类的this指针指向内存模型中的基类首地址 根据继承性原理,这里的this指针指向派生类的对象
{
if (lpszAppName != NULL) //指定应用程序的名字,分配字符串lpszAppName长度的内存,然后返回地址指针赋给m_pszAppName
m_pszAppName = _tcsdup(lpszAppName);
else
m_pszAppName = NULL;
// initialize CWinThread state //用来管理模块(EXE/DLL文件)和线程状态数据的。Call this macro to protect an exported function in a DLL //AFX_MANAGE_STATE的作用切换到指定的Module State,当出了作用域的时候将Module State恢复到原来的值
//module 就是一个 PE文件,如:模块名称、模块基址、资源地址、是否DLL,是否系统模块,还有主线程对象,导入dll链 //表,OLE控制信息等
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); //线程状态信息,即模块线程的初始信息
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
ASSERT(AfxGetThread() == NULL); //一个单文档的MFC程序通过构造一个全局对象,将应用程序的实例对象传递给它的基类CWinApp //this指针代表的是应用程序的实例对象,参考this指针用法
pThreadState->m_pCurrentWinThread = this; //AfxGetThread()返回的是当前界面线程对象的指针
ASSERT(AfxGetThread() == this); //返回当前线程的虚拟句柄
m_hThread = ::GetCurrentThread(); //返回当前线程 ID
m_nThreadID = ::GetCurrentThreadId();
// initialize CWinApp state //afxCurrentWinApp是一个宏,#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
pModuleState->m_pCurrentWinApp = this; //AfxGetApp()返回的是应用程序对象的指针
ASSERT(AfxGetApp() == this);
// in non-running state until WinMain
m_hInstance = NULL; //标识应用程序的当前实例。
m_pszHelpFilePath = NULL; //应用程序的帮助文件的路径。
m_pszProfileName = NULL; //应用程序的 .INI 文件名。
m_pszRegistryKey = NULL; //用于确定存储应用程序配置文件设置完整的注册表项
m_pszExeName = NULL; //应用程序的模块名称
m_pRecentFileList = NULL; //
m_pDocManager = NULL; //
m_atomApp = m_atomSystemTopic = NULL; //
m_lpCmdLine = NULL; //指向指定应用程序的命令行以 NULL 结尾的字符串。
m_pCmdInfo = NULL; //
// initialize wait cursor state
m_nWaitCursorCount = 0; //
m_hcurWaitCursorRestore = NULL; //
// initialize current printer state
m_hDevMode = NULL; //
m_hDevNames = NULL; //
m_nNumPreviewPages = 0; // not specified (defaults to 1)
// initialize DAO state
m_lpfnDaoTerm = NULL; // will be set if AfxDaoInit called
// other initialization
m_bHelpMode = FALSE; //
m_nSafetyPoolSize = 512; // default size
} CWinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置和初始值
CWinApp封装用于 Windows 操作系统的应用程序的初始化、运行和终止
CWinApp 是从 CWinThread 派生的,后者表示可能具有一个或多个线程的应用程序的主执行线程。
创建一个应用程序对象,为对象创建一个线程,并设置线程的初始信息,最后返回应用程序对象指针
(2)关键字“WinMain”
参考《MFC自动调用Appmodul.cpp》http://www.cnblogs.com/xuemaxiongfeng/articles/2467958.html
(3)AfxWinMain
在WINMAIN.CPP中
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
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)
{
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;
}
MFC状态信息,包括模块,进程,线程状态信息。
具体可以查看
AFX_MODULE_PROCESS_STATE
AFX_MODULE_STATE
AFX_THREAD_STATE 派生类的内存模型是,先构造基类然后构造派生类。而派生类的this指针指向内存模型中的基类首地址 根据继承性原理,这里的this指针指向派生类的对象
Mfc程序(EXE)的程序运行过程如下:
首先是全局构造
CObject构造函数à CCmdTarget àCWinThreadàCWinAppà theApp构造函数
然后进入WinMain函数
WinMainàAfxWinMainàAfxWinInitàtheApp.InitApplicationàtheApp.InitInstance
接着执行线程过程。
theApp.Run()
最后清理
AfxWinTerm

浙公网安备 33010602011771号