按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
CWinApp* pApp = AfxGetApp();
return TRUE;
AfxWinInit(。。。); }
AfxWinInit(。。。);
pApp…》InitApplication(); CMyFrameWnd::CMyFrameWnd()
pApp…》InitApplication();
pApp…》InitInstance(); {
pApp…》InitInstance();
nReturnCode = pApp…》Run(); Create(NULL; 〃Hello MFC〃; 。。。;
nReturnCode = pApp…》Run();
〃MainMenu〃);
AfxWinTerm(); }
AfxWinTerm();
}
}
void CMyFrameWnd::OnPaint() { 。。。 }
void CMyFrameWnd::OnAbout() { 。。。 }
BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
ON_MAND(IDM_ABOUT; OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
theApp 配置完成后,WinMain 登场。我们并未撰写WinMain 程序代码,这是MFC 早已
准备好并由联结器直接加到应用程序代码中的,其源代码列于图6…4 。_tWinMain 函数的
! §…t! ¨ 是为了支持Unicode 而准备的一个宏。
// in APPMODUL。CPP
extern 〃C〃 int WINAPI
_tWinMain (HINSTANCE hInstance; HINSTANCE hPrevInstance;
LPTSTR lpCmdLine; int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain (hInstance; hPrevInstance; lpCmdLine; nCmdShow);
}
此外,在DLLMODUL。CPP 中有一个DllMain 函数。本书并未涵盖DLL 程序设计。
366
…………………………………………………………Page 429……………………………………………………………
第6章 MFC 程式的生死因果
// in WINMAIN。CPP
#0001 /////////////////////////////////////////////////////////////////
#0002 // Standard WinMain implementation
#0003 // Can be replaced as long as 'AfxWinInit' is called first
#0004
#0005 int AFXAPI AfxWinMain (HINSTANCE hInstance; HINSTANCE hPrevInstance;
#0006 LPTSTR lpCmdLine; int nCmdShow)
#0007 {
#0008 ASSERT(hPrevInstance == NULL);
#0009
#0010 int nReturnCode = …1;
#0011 CWinApp* pApp = AfxGetApp();
#0012
#0013 // AFX internal initialization
#0014 if (!AfxWinInit(hInstance; hPrevInstance; lpCmdLine; nCmdShow))
#0015 goto InitFailure;
#0016
#0017 // App global initializations (rare)
#0018 ASSERT_VALID(pApp);
#0019 if (!pApp…》InitApplication())
#0020 goto InitFailure;
#0021 ASSERT_VALID(pApp);
#0022
#0023 // Perform specific initializations
#0024 if (!pApp…》InitInstance())
#0025 {
#0026 if (pApp…》m_pMainWnd != NULL)
#0027 {
#0028 TRACE0(〃Warning: Destroying non…NULL m_pMainWndn〃);
#0029 pApp…》m_pMainWnd…》DestroyWindow();
#0030 }
#0031 nReturnCode = pApp…》ExitInstance();
#0032 goto InitFailure;
#0033 }
#0034 ASSERT_VALID(pApp);
#0035
#0036 nReturnCode = pApp…》Run();
#0037 ASSERT_VALID(pApp);
#0038
#0039 InitFailure:
#0040
#0041 AfxWinTerm();
#0042 return nReturnCode;
#0043 }
图6…4 Windows 程序进入点。源代码可从MFC 的WINMAIN。CPP 中获得。
367
…………………………………………………………Page 430……………………………………………………………
第篇 湷觥 FC 程式設計
稍加整理去芜存菁,就可以看到这个「程序进入点」主要做些什么事:
int AFXAPI AfxWinMain (HINSTANCE hInstance; HINSTANCE hPrevInstance;
LPTSTR lpCmdLine; int nCmdShow)
{
int nReturnCode = …1;
CWinApp* pApp = AfxGetApp();
AfxWinInit(hInstance; hPrevInstance; lpCmdLine; nCmdShow);
pApp…》InitApplication();
pApp…》InitInstance();
nReturnCode = pApp…》Run();
AfxWinTerm();
return nReturnCode;
}
其中,AfxGetApp 是一个全域函数,定义于AFXWIN1。INL 中:
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
{ return afxCurrentWinApp; }
而afxCurrentWinApp 又定义于AFXWIN。H 中:
#define afxCurrentWinApp AfxGetModuleState()…》m_pCurrentWinApp
再根据稍早所述CWinApp::CWinApp 中的动作,我们于是知道,AfxGetApp 其实就是取
得CMyWinApp 对象指针。所以,AfxWinMain 中这样的动作:
CWinApp* pApp = AfxGetApp();
pApp…》InitApplication();
pApp…》InitInstance();
nReturnCode = pApp…》Run();
其实就相当于调用:
CMyWinApp::InitApplication();
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();