题外:
1、和SDK编程不一样,MFC框架中的WinMain是通过连接加入工程的,所以直接搜索不到。可以再MFC/SRC中搜索,WinMain保存在APPMODUL.CPP。
2、不管是那种编程方式,程序不总是从main或WinMain执行,至少全局变量或全局对象要先一步的分配内存或者构造。
分析:
1、产生全局对象theApp(CTestApp.cpp),这个对象代表着当前MFC工程应用程序:
CTestApp theApp;
2、theApp对象的产生需要构造函数,而class CTestApp : public CWinApp,同时调用子类的构造函数前,需要调用基类的构造函数,所以CWinApp::CWinApp(appcore.cpp)被调用。其中:
pModuleState->m_pCurrentWinApp = this;
this是子类对象,在此成为基类成员变量。
3、WinMain(APPMODUL.CPP)的实际执行者AfxWinMain(WINMAIN.CPP)中,有如下重要代码:
……
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
getthread通常和Getapp作用一样,用于获取第2步保存的子类对象theApp。
……
pApp->InitApplication()
一些初始化工作
……
pThread->InitInstance()
pThread即theApp对象指针,所以这里调用子类CTestApp::InitInstance(),在这个函数中窗口显示,更新。
……
pThread->Run();
这里完成消息循环。实际调用CWinThread::Run()(THRDCORE.CPP)完成消息循环。
4、窗口的设计主要在PreCreateWindow完成。
CMainFrame::PreCreateWindow(CREATESTRUCT& cs)中调用基类的
CFrameWnd::PreCreateWindow(cs) (WINFRM.CPP)中调用
AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)(WINCORE.CPP),同时在afximpl.h中:
#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
BOOL AFXAPI AfxEndDeferRegisterClass()(WINCORE.CPP)这个函数中完成设计窗口类,并注册窗口类。
5、创建窗口最终是由CreateWindowEx函数完成。
CFrameWnd::LoadFrame调用 CFrameWnd::Create (winfrm.cpp)
Create函数中调用CreateEx,CreateEx函数在CFrameWnd没有重写,所以调用的是基类的
CWnd::CreateEx(wincore.cpp)
{
……
PreCreateWindow(cs);
……
::CreateWindowEx();
}
上面PreCreateWindow(cs)是虚函数,这里调用的实际是子类的PreCreateWindow,因为CreateEx本省就是被子类调用。