VC++深入详解:消息循环2010-05-27至此,注册窗口类、创建窗口、显示和更新窗口的工作都已完成,就该进入消息循环了。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-17BOOL 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编程的消息处理代码是一致的。