按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
7
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
8
return TRUE;
2 }
AfxWinInit(。。。);
3 CMyFrameWnd::CMyFrameWnd()
pApp…》InitApplication();
pApp…》InitInstance(); {
4
6
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()
CMyFrameWnd::CMyFrameWnd 结束后, 窗口已经诞生出来; 程序流程又回到
CMyWinApp::InitInstance , 于是调用ShowWindow 函数令窗口显示出来, 并调用
UpdateWindow 函数令Hello 程序送出WM_PAINT 消息。
我们很关心这个WM_PAINT 消息如何送到窗口函数的手中。而且,窗口函数又在哪里?
MFC 程序是不是也像SDK 程序一样,有一个GetMessage/DispatchMesage 循环?是否
每个窗口也都有一个窗口函数,并以某种方式进行消息的判断与处理?
两者都是肯定的。我们马上来寻找证据。
389
…………………………………………………………Page 452……………………………………………………………
第篇 湷觥 FC 程式設計
CWinApp::Run 程序生命的活水源头
HELLO。CPP
1 CMyWinApp theApp; // application object
WINMAIN。CPP
BOOL CMyWinApp::InitInstance()
int AFXAPI AfxWinMain (。。。)
{
{
5
m_pMainWnd = new CMyFrameWnd();
CWinApp* pApp = AfxGetApp();
m_pMainWnd…》ShowWindow(m_nCmdShow);
7
m_pMainWnd…》UpdateWindow();
2 8
AfxWinInit(。。。);
return TRUE;
3 }
pApp…》InitApplication();
pApp…》InitInstance();
4
CMyFrameWnd::CMyFrameWnd()
nReturnCode = pApp…》Run();
9 {
6
Create(NULL; 〃Hello MFC〃; 。。。;
AfxWinTerm();
〃MainMenu〃);
}
CWinApp::Run }
CWinApp::Run
CWinThread::Run void CMyFrameWnd::OnPaint() { 。。。 }
do { void CMyFrameWnd::OnAbout() { 。。。 }
do {
::GetMessage(&msg;。。。);
::GetMessage(&msg;。。。);
PreTranslateMessage{&msg);
PreTranslateMessage{&msg); BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
::TranslateMessage(&msg);
::TranslateMessage(&msg);
::DispatchMessage(&msg); ON_MAND(IDM_ABOUT; OnAbout)
::DispatchMessage(&msg);
。。。 ON_WM_PAINT()
。。。
} while (::PeekMessage(。。。)); END_MESSAGE_MAP()
} while (::PeekMessage(。。。));
DefWindowProc
DefWindowProc AfxWndProc
hooking and subclassing AfxWndProc
(please see chap9; p。560;
“Minotauros and Theseus”)
Hello 程序进行到这里,窗口类别注册好了,窗口诞生并显示出来了,UpdateWindow 被
调用,使得消息队列中出现了一个WM_PAINT 消息,等待被处理。现在,执行的脚步到
达pApp …》Run 。
稍早我说过了,pApp 指向CMyWinApp 对象(也就是本例的theApp ),所以,当程序
调用:
pApp…》Run();
相当于调用:
CMyWinApp::Run();
390
…………………………………………………………Page 453……………………………………………………………
第6章 MFC 程式的生死因果
要知道,CMyWinApp 继承自CWinApp,而Run 又是CWinApp 的一个虚拟函数。我们
并没有改写它(大部份情况下不需改写它),所以上述动作相当于调用:
CWinApp::Run();
其源代码出现在APPCORE。CPP 中:
int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation; but has no main window!
TRACE0(〃Warning: m_pMainWnd is NULL in CWinApp::Run quitting
application。n〃);
AfxPostQuitMessage(0);
}
return CWinThread::Run();
}
32 位MFC 与16 位MFC 的巨大差异在于CWinApp 与CCmdTarget 之间多出了一
个CWinThread,事情变得稍微复杂一些。CWinThread 定义于THRDCORE。CPP :
int CWinThread::Run()
{
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received。
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur; NULL; NULL; NULL; PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume 〃no idle〃 state
}
// phase2: pump messages while available
do
{
// pump message; but quit on WM_QUIT
391
…………………………………………………………Page 454……………………………………………………………
第篇 湷觥 FC 程式設計
if (!