C**App theApp;
//这个全局变量就是代表一个程序,并且它是在WinMain函数执行之前就创建了.然后执行其构造函数
//但是这个类是C**App::public CWinApp的,所以要先执行其父类的构造函数. CWinApp::CWinApp()
{
......
AFX_MODULE_STATE *pModuleState = AfxGetModuleState();
pModuleState->m_pCurrentWinApp = this;
......
}
//由于这个构造函数被派生类C**App继承过来了,所以这个this就是theApp,然后还会执行一些相关的信息
//然后就是WinMain函数开始执行了.
int AFXAPI AfxWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
CWinThread *pThread = AfxGetThread();
CWinApp *pApp = AfxGetApp();
if( pApp != NULL && !pApp->InitApplication() )
goto InitFailure;
if( !pThread->InitInstance() )
{
if( pThread->m_pMainWnd != NULL )
{
TRACE0("......");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturCode = pThread->Run();
//Run()函数就是开始执行消息循环的函数.
}
//WinMain函数的主要作用就是来调用InitApplication,InitInstance,Run三个函数.
CWinThread *AFXAPI AfxGetThread()
{
AFX_MODULE_THREAD_STATE *pState = AfxGetModuleThreadState();
CWinThread *pThread = pState->m_pCurrentWinThread;
if( pThread == NULL )
{
pThread = AfxGetApp();
}
}
_AFXWIN_INLINE CWinApp *AFXAPI AfxGetApp()
{
return afxCurrentWinApp;
}
#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
//上面的两个函数和一个宏定义,虽然两个函数的名字不同,但是实际上都是返回m_pCurrentWinApp,上面构造函数中也看到了m_pCurrentWinApp的值其实就是theApp;
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;
return TRUE;
}
//这个函数大概就是文档类管理的,侯水货说要再后面几章节讲述,到时候我补上.上述的函数虽然是在CWinApp类中定义的,但是我们的C**App类派生自CWinApp,并且我们并没有改写InitApplication函数,所以实际上还是调用基类的函数.
BOOL C**WinApp::InitInstance()
{
m_pMainWnd = new CMyFrameWnd();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
//以上代码是MFC深入浅出里面的,但是在VC++深入详解确实这样写的: pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(C**Doc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(C**View));
AddDocTemplate(pDocTemplate);
//上述代码居然用到了RUNTIME_CLASS这个宏定义,感觉无限熟悉啊,看
来MFC的这几个精髓的宏我要看透了.
}
//为什么我这个这个函数的类不是CWinApp了,因为我们改写了这个函数,而且是必须改写的.并且这个是虚函数,所以是调用了子类theApp的InitInstance函数.
//而且第一句的函数就是来创建一个CFrameWnd对象,那么看一下CFrameWnd干什么了.
CFrameWnd::CFrameWnd()
{
Create(NULL,"Hello
MFC",WS_OVERLAPPEDWINDOW,rectDefault,NULL,"MainMenu");
}
//这个函数就是用来产生窗口的,但是在产生窗口之前,还没有注册窗口呢?也没有设置窗口的属性啊?所以在这个函数调用之前还需要调用一个函数CFrameWnd::Create(LPCRSTR lpszClassName,LPCTSTR lpszWindowName,DOWRD dwStyle = WS_OVERLAPPEDWINDOW,const RECT& rect = rectDefault,)
{
HMENU hMenu = NULL;
if( lpszMenuName != NULL )
{
hMenu = ::LoadMenu(hInst,lpszMenuName);
//加载菜单
}
CreateEx(...);
}
CFrameWnd::CreateEx()
{
}
//CreateEx是一个虚函数,并且CFrameWnd是派生自CWnd,并且没有改变虚函数,所以实际上就是调用CWnd::CreateEx函数.
BOOL CWnd::CreatEx()
{
//填充cs对象,它的类型是WNDCASS
PreCreateWindow(cs)
//重要的是这个函数PreCreateWindow(cs)
}
BOOL CFrameWnd::PreCreateWindow(CREATESTUCT &cs)
{
if( cs.lpszClass == NULL )
{
AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);
...
}
...
}
//此处需要说明一下我们自己创建的程序应该有一个C**FrameWnd类,里面同样有一个PreCreateWindow
BOOL C**FrameWnd::PreCreateWindow(CREATESTRUCT &cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
{
return FALSE;
}
// TO DO SOMETHING
//这个函数是继承过来的,并且首先点调用基类的PreCreateWindow先完成窗口的注册,如果我们要改变系统为
//我们创建的默认窗口的话,在这个函数里面修改就可以了,并且直接修改cs 就可以了,因为是引用.
}
#define AfxDeferRegisterClass(fClass) ((afxRegisteredClasses &fClass)?TRUE:AfxEndDeferRegisterClass(fClass))
#define afxRegisteredClasses AfxGetModuleState()->m_fRegisteredClasses
//实际上就是用我们定义的全局对象来注册窗口而已
BOOL AFXAPI AfxEndDeferRegisterClass(short fClass)
{
AfxRegisterClass(...);
RegisterWithIcon(...);
//主要工作就是调用这两个函数
}
//函数定义如下
static BOOL AFXPAI RegisterWithIcon(WNDCLASS *pWndCls...)
{
//会加载图标
return AfxRegisterClass(pWndCls);
}
BOOL AFXAPI AfxRegisterClass(WNDCLASS *lpWndClass)
{
::RegisterClass(lpWndClass);
//调用全局的RegisterClass函数来完成注册
}