1. 程式人生 > >[轉]關於VC++ MFC中的空閑Idle處理機制!

[轉]關於VC++ MFC中的空閑Idle處理機制!

normal 函數 系統 true check track cor idle 行處理

關鍵詞:

  先根據空閑標誌以及消息隊列是否為空這兩個條件判斷當前線程是否處於空閑狀態(這個“空閑”的含義同操作系統的含義不同,是MFC自己所謂的“空閑”),如果是,就調用CWinThread::OnIdle(),這也是我們比較熟悉的一個虛擬函數。
如果不是,從消息隊列中取出消息,進行處理,直到消息隊列為空。
/thrdcore.cpp
// 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 }

  在這裏,我們發現,MFC不是調用GetMessage()從線程消息隊列中取消息,而是調用PeekMessage()。其原因在 於,GetMessage()是一個具有同步行為的函數,如果消息隊列中沒有消息,GetMessage()會一直阻塞,使得線程處於睡眠狀態,直到消息 隊列中有一條或多條消息,操作系統才會喚醒該線程,GetMessage()才會返回,如果線程處於睡眠狀態了,就不會使線程具有MFC所謂的“空閑”狀 態了;而PeekMessage()則是一個具有異步行為的函數,如果消息隊列中沒有消息,它馬上返回0,不會導致線程處於睡眠狀態。

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;

}

  首先,PumpMessage()調用GetMessage()從消息隊列中取一條消息,由於PumpMessage()是在消息隊列中有消息的時候才被調用的,所以GetMessage()會馬上返回, 根據其返回值,判斷當前取出的消息是不是WM_QUIT消息(這個消息一般對是通過調用PostQuitMessage()放入線程消息隊列的),如果 是,就返回FALSE,CWinThread::Run()該退出了,CWinThread::Run()直接調用 CWinThread::ExitInstance()退出應用程序。在GetMessage()的後面是我們所熟悉的 TranslateMessage()和DispatchMessage()函數。
  可以看出,是否調用TranslateMessage()和DispatchMessage()是由一個名稱為PreTranslateMessage()函數的返回值決定的,如果該函數返回TRUE,則不會把該消息分發給窗口函數處理。

  文章轉載自:羅索實驗室 [http://www.rosoo.net/a/201102/10850.html]

[轉]關於VC++ MFC中的空閑Idle處理機制!