至此,注冊窗口類、創建窗口、顯示和更新窗口的工作都已完成,就該進入消息循環了。CWinThread類的Run函數就是完成消息循環這一任務的,該函數是在AfxWinMain函數中調用的,調用形式如下(位於例3-7所示AfxWinMain函數實現代碼的符號④處)所示。
pThread->Run();
CWinThread類的Run函數的定義位於THRDCORE.CPP文件中,代碼如例3-16所示。
例3-16
// main running routine until thread exits
int CWinThread::Run()
{
ASSERT_VALID(this);
// 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
if (!PumpMessage())
return ExitInstance();
// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
ASSERT(FALSE); // not reachable
}
該函數的主要結構是一個for循環,該循環在接收到一個WM_QUIT消息時退出。在此循環中調用了一個PumpMessage函數,該函數的部分定義代碼如例3-17所示。
例3-17
BOOL CWinThread::PumpMessage()
{
ASSERT_VALID(this);
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
……
return FALSE;
}
……
// process this message
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_ msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
}
return TRUE;
}
可以發現,這與前面第2章中講述的SDK編程的消息處理代碼是一致的。