文档库 最新最全的文档下载
当前位置:文档库 › MFC初始化机制

MFC初始化机制

MFC初始化机制
MFC初始化机制

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函数来完成注册

}

相关文档