zoukankan      html  css  js  c++  java
  • [转]关于VC++ MFC中的空闲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]

  • 相关阅读:
    Java正則表達式入门
    Effect of Switchovers, Failovers, and Control File Creation on Backups
    Android 屏幕截图(底层实现方式)
    Java实现奇偶数排序
    Java实现奇偶数排序
    Java实现奇偶数排序
    Java实现找零问题
    Java实现找零问题
    Java实现找零问题
    Java实现找零问题
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/6849058.html
Copyright © 2011-2022 走看看