友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
深入浅出MFC第2版(PDF格式)-第51部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
CMyWinApp::InitInstance();
CMyWinApp::Run();
因而导至调用:
CWinApp::InitApplication(); // 因为 CMyWinApp 并没有改写InitApplication
CMyWinApp::InitInstance(); // 因为 CMyWinApp 改写了 InitInstance
CWinApp::Run(); //因为 CMyWinApp 并没有改写Run
368
…………………………………………………………Page 431……………………………………………………………
第6章 MFC 程式的生死因果
根据第1章SDK 程序设计的经验推测,InitApplication 应该是注册窗口类别的场所?
InitInstance 应该是产生窗口并显示窗口的场所?Run 应该是攫取消息并分派消息的场
所?有对有错!以下数节我将实际带你看看MFC 的源代码,如此一来就可以了解隐藏
在MFC 背后的玄妙了。我的终极目标并不在MFC 源代码(虽然那的确是学习设计一个
application framework 的好教材),我只是想拿把刀子把MFC 看似朦胧的内部运作来个
大解剖,挑出其经脉;有这种扎实的根基,使用MFC 才能知其然并知其所以然。下面小
节分别讨论AfxWinMain 的四个主要动作以及引发的行为。
369
…………………………………………………………Page 432……………………………………………………………
第篇 湷觥 FC 程式設計
AfxWinInit-AFX 内部初始化动作
HELLO。CPP
1 CMyWinApp theApp; // application object
BOOL CMyWinApp::InitInstance()
WINMAIN。CPP
{
int AFXAPI AfxWinMain (。。。) m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
return TRUE;
2 AfxWinInit(。。。); }
pApp…》InitApplication(); CMyFrameWnd::CMyFrameWnd()
pApp…》InitInstance(); {
nReturnCode = pApp…》Run(); Create(NULL; 〃Hello MFC〃; 。。。;
〃MainMenu〃);
AfxWinTerm(); }
}
void CMyFrameWnd::OnPaint() { 。。。 }
void CMyFrameWnd::OnAbout() { 。。。 }
BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
ON_MAND(IDM_ABOUT; OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
我想你已经清楚看到了,AfxWinInit 是继CWinApp 构造式之后的第一个动作。以下是它
的动作摘要(节录自APPINIT。CPP ):
BOOL AFXAPI AfxWinInit(HINSTANCE hInstance; HINSTANCE hPrevInstance;
LPTSTR lpCmdLine; int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
// set resource handles
AFX_MODULE_STATE* pState = AfxGetModuleState();
pState…》m_hCurrentInstanceHandle = hInstance;
pState…》m_hCurrentResourceHandle = hInstance;
// fill in the initial state for the application
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
{
// Windows specific initialization (not done if no CWinApp)
370
…………………………………………………………Page 433……………………………………………………………
第6章 MFC 程式的生死因果
pApp…》m_hInstance = hInstance;
pApp…》m_hPrevInstance = hPrevInstance;
pApp…》m_lpCmdLine = lpCmdLine;
pApp…》m_nCmdShow = nCmdShow;
pApp…》SetCurrentHandles();
}
// initialize thread specific data (for main thread)
if (!afxContextIsDLL)
AfxInitThread();
return TRUE;
}
其中调用的AfxInitThread 函数的动作摘要如下(节录自THRDCORE。CPP ):
void AFXAPI AfxInitThread()
{
if (!afxContextIsDLL)
{
// attempt to make the message queue bigger
for (int cMsg = 96; !SetMessageQueue(cMsg) && (cMsg …= 8); )
;
// set message filter proc
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
ASSERT(pThreadState…》m_hHookOldMsgFilter == NULL);
pThreadState…》m_hHookOldMsgFilter = ::SetWindowsHookEx(WH_MSGFILTER;
_AfxMsgFilterHook; NULL; ::GetCurrentThreadId());
// intialize CTL3D for this thread
_AFX_CTL3D_STATE* pCtl3dState = _afxCtl3dState;
if (pCtl3dState…》m_pfnAutoSubclass != NULL)
(*pCtl3dState…》m_pfnAutoSubclass)(AfxGetInstanceHandle());
// allocate thread local _AFX_CTL3D_THREAD just for automatic termination
_AFX_CTL3D_THREAD* pTemp = _afxCtl3dThread;
}
}
如果你曾经看过本书前身Visual C++ 对象导向 MFC 程序设计,我想你可能对这句话
印象深刻:「WinMain 一开始即调用AfxWinInit ,注册四个窗口类别」。这是一个已成
昨日黄花的事实。MFC 的确会为我们注册四个窗口类别,但不再是在AfxWinInit 中完
成。稍后我会把注册动作挖出来,那将是窗口诞生前一刻的行为。
371
…………………………………………………………Page 434……………………………………………………………
第篇 湷觥 FC 程式設計
CWinApp::InitApplication
HELLO。CPP
1 CMyWinApp theApp; // application object
BOOL CMyWinApp::InitInstance()
WINMAIN。CPP
{
int AFXAPI AfxWinMain (。。。) m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
return TRUE;
2 }
AfxWinInit(。。。);
3 pApp…》InitApplication(); CMyFrameWnd::CMyFrameWnd()
pApp…》InitInstance(); {
nReturnCode = pApp…》Run(); Create(NULL; 〃Hello MFC〃; 。。。;
〃MainMenu〃);
AfxWinTerm(); }
}
void CMyFrameWnd::OnPaint() { 。。。 }
void CMyFrameWnd::OnAbout() { 。。。 }
BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
ON_MAND(IDM_ABOUT; OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
AfxWinInit 之后的动作是pApp …》InitApplication 。稍早我说过了,pApp 指向CMyWinApp
对象(也就是本例的theApp ),所以,当程序调用:
pApp…》InitApplication();
相当于调用:
CMyWinApp::InitApplication();
但是你要知道,CMyWinApp 继承自CWinApp,而InitApplication 又是CWinApp 的一个
虚拟函数;我们并没有改写它(大部份情况下不需改写它),所以上述动作相当于调用:
CWinApp::InitApplication();
此函数之源代码出现在APPCORE。CPP 中:
372
…………………………………………………………Page 435……………………………………………………………
第6章 MFC 程式的生死因果
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;
}
这些动作都是MFC 为了内部管理而做的。
关于Document Template 和CDocManager ,第7章和第8章另有说明。
373
…………………………………………………………Page 436……………………………………………………………
第篇 湷觥 FC 程式設計
CMyWinApp::InitInstance
HELLO。CPP
1 CMyWinApp theApp; // application object
WINMAIN。CPP BOOL CMyWinApp::InitInstance()
{
int AFXAPI AfxWinMain (。。。) m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
return TRUE;
2 }
AfxWinInit(。。。);
3 CMyFrameWnd::CMyFrameWnd()
pApp…》InitApplication();
pApp…》InitInstance(); {
4
nReturnCode = pApp…》Run(); Create(NULL; 〃Hello MFC〃; 。。。;
〃MainMenu〃);
AfxWinTerm(); }
}
void CMyFrameWnd::OnPaint() { 。。。 }
void CMyFrameWnd::OnAbout() { 。。。 }
BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
ON_MAND(IDM_ABOUT; OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
继InitApplication 之后,AfxWinMain 调用pApp …》InitInstance 。稍早我说过了,pApp 指向
CMyWinApp 对象(也就是本例的theApp ),所以,当程序调用:
pApp…》InitInstance();
相当于调用
CMyWinApp::InitInstance();
但是你要知道,CMyWinApp 继承自CWinApp,而InitInstance 又是CWinApp 的一个虚
拟函数。由于我们改写了它,所以上述动作的的确确就是调用我们自己(CMyWinApp)
的这个InitInstance 函数。我们将在该处展开我们的主窗口生命。
374
…………………………………………………………Page 437……………………………………………………………
第6章 MFC 程式的生死因果
APPCORE。CPP
base class virtual BOOL InitApplication();
virtual BOOL InitInstance();
CWinApp
virtual int Run();
virtual int ExitInstance();
HELLO。CPP overridden
virtual BOOL InitInstance();
CMyWinApp
derived class
般而言,CMyWinApp 只改寫
CWinApp 的 InitInstance ,通常
它不改寫 InitApplication 和 Run 。
注意:应用程序一定要改写虚拟函数InitInstance ,因为它在CWinApp 中只是个空函数,
没有任何内建(预设)动作。
375
…………………………………………………………Page 438……………………………………………………………
第篇 湷觥 FC 程式設計
CFrameWnd::Create 产生主窗口(并先注册窗口类别)
HELLO。CPP
1 CMyWinApp theApp; // application object
BOOL CMyWinApp::InitInstance()
WINMAIN。CPP
{
int AFXAPI AfxWinMain (。。。) 5 m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
return TRUE;
2 }
AfxWinInit(。。。);
3 CMyFrameWnd::CMyFrameWnd()
pApp…》InitApplication();
pApp…》InitInstance(); {
4
6 Create(NULL; 〃Hello MFC〃; 。。。;
nReturnCode = pApp…》Run();
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!