一、Frame8程序main函数第2-4行
pApp->InitApplication();
pApp->InitInstance();
pApp->Run();
这几个的函数的前提是:
CMyWinApp theApp; // global object
CWinApp* pApp = &theApp
1,pApp->InitApplication();
这个函数在CMyWinApp这没有重新定义,继续看它的基类:
class CWinApp : public CWinThread
{
public:
CWinApp* m_pCurrentWinApp;
CWnd* m_pMainWnd; //为什么要定义这个新的变量
public:
CWinApp::CWinApp() {
m_pCurrentWinApp = this;
}
CWinApp::~CWinApp() {
}
virtual BOOL InitApplication() {
cout << "CWinApp::InitApplication /n";
return TRUE;
}
再看CWinApp的基类CWinThread:
其中没有InitApplication函数的声名。
InitApplication函数是从CWinApp起源的。
所以第二句pApp->InitApplication();执行的就是:
virtual BOOL CWinApp ::InitApplication() {
cout << "CWinApp::InitApplication /n";
return TRUE;
}
这里就有一个有意思的问题:
CMyWinApp theApp; // global object
CWinApp* pApp = &theApp
调用pApp->InitApplication()时,InitApplication是虚函数,首先看CMyWinApp中有没有实现,有重写的实现当然是调用之,现在是没有,所以去调用其基类的InitApplication,现在假设InitApplication函数是从CWinThread起源的虚函数,CWinThread:: InitApplication会被理会吗?修改代码试一下,结果是没有理会。
其实这个问题的实质是虚函数的管理机制,《深入浅出》也是有介绍的,可以抽时间看看。
2, 第三句pApp->InitInstance();
在CMyWinApp中这个函数进行了重写。
class CMyWinApp : public CWinApp
{
public:
CMyWinApp::CMyWinApp() {
}
CMyWinApp::~CMyWinApp() {
}
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
毫无疑问,这次的执行就是它了:
BOOL CMyWinApp::InitInstance()
{
cout << "CMyWinApp::InitInstance /n";
m_pMainWnd = new CMyFrameWnd;
return TRUE;
}
其中的m_pMainWnd是CWinApp的成员。这和真实的MFC应该差别不大。
这个new语句会调用CMyFrameWnd,其中有些打印语句用来表示真实情况下可能做了些什么。
CMyFrameWnd::CMyFrameWnd()
{
Create(); // 这个函数是从CWnd起源的一个虚函数,被CFrameWnd重写
}
所以就执行下面的语句:
BOOL CFrameWnd::Create()
{
cout << "CFrameWnd::Create /n";
CreateEx(); // 这个函数不是虚函数,是CWnd的一个成员函数。
return TRUE;
}
BOOL CWnd::CreateEx()
{
cout << "CWnd::CreateEx /n";
PreCreateWindow();
return TRUE;
}
BOOL CWnd::PreCreateWindow()
{
cout << "CWnd::PreCreateWindow /n";
return TRUE;
}
综合起来,pApp->InitInstance();的输出就是:
cout << "CMyWinApp::InitInstance /n";
cout << "CFrameWnd::Create /n";
cout << "CWnd::CreateEx /n";
cout << "CWnd::PreCreateWindow /n";
这句话想告诉的是一个自定义的CMyWinApp实例初始化的过程(如果其中是使用Frame界面的话):
A, 先做CMyWinApp::InitInstance自己App实例的初始化
B, CMyFrameWnd在构造函数中进行一些初始化,Frame和界面相关的
C, 再调用CFrameWnd类(MFC提供)的Create
D,CWnd的CreateEx
E, CWnd的PreCreateWindow,后3条都是MFC写好的,虽然改动的可能性很小,但明白一下肯定很有意义。
3,第四句pApp->Run();
原型是CMyWinApp::Run, Run是CWinThread起源的一个虚函数。
CMyWinApp没有重写,但是其基类CWinApp是重写了这个Run函数的,所以继续调用
virtual int Run() {
cout << "CWinApp::Run /n";
return CWinThread::Run();
}
virtual int CWinThread::Run() {
cout << "CWinThread::Run /n";
// AfxWndProc(...); 原本在这里开始消息循环了
return 1;
}
输出很明显了
cout << "CWinApp::Run /n";
cout << "CWinThread::Run /n";
表达的调用意义:
分别调用MFC提供的CWinApp和CWinThread的Run函数。
明天继续Frame8的其他原理分析。