关键词:

  先根据空闲标志以及消息队列是否为空这两个条件判断当前线程是否处于空闲状态(这个“空闲”的含义同操作系统的含义不同,是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 = ; // 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 = ;
} } 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处理机制!的更多相关文章

  1. VC/MFC中计算程序运行时间

    转自原文VC/MFC中计算程序运行时间 说明,这四种方法也分别代表了类似的实现,在MFC中,所可以从哪些类集合去考虑. 方法一 利用GetTickCount函数(ms) CString str; lo ...

  2. VC++ MFC中如何将应用程序的配置信息保存到注册表中(二)

    在上一篇中介绍了几个写入注册表数据和读取注册表数据的接口,并介绍了使用方法. 这一片教你如何使得你的应用程序在下次打开时保持上一次关闭前的状态. 在上一篇添加的代码的基础上,要添加WM_CLOSE消息 ...

  3. 在VC/MFC中嵌入Google地图——图文并茂

    近期须要实验室须要将在无人机地面站中嵌入地图,在网上找了非常多资料,最终有些眉目了, 首先.做这个须要用到的知识有.MFC控件.MFC类库.JavaScript脚本语言.Google API.Goog ...

  4. VC++/MFC中调用CHM帮助文档的方法

    转载:http://blog.csdn.net/hediping9811/article/details/23341387 (1)用Word编辑好帮助文档,并保存为网页格式,如mhtml格式. (2) ...

  5. VC/MFC中为程序定义全局快捷键

    VC 2010-05-01 18:01:34 阅读287 评论0 字号:大中小 订阅 1.注册快捷键 在初始化函数,如OnInitDialog() 注册快捷键,代码如下: #define HotKey ...

  6. VC/MFC中的CComboBox控件使用详解

    CComboBox控件详解 CComboBox控件又称作组合框控件,其有三种形态可供选择,1.简单组合框(Simple)2.下拉组合框(Drop-down)3.下拉列表式组合框(Drop-down l ...

  7. vc++ mfc中拖动效果的实现 借助于CImageList

    拖动是界面编程频繁使用的一个效果,在windows系统下可谓大行其道.纵观时下的应用软件几乎各个都支持各种各样拖动的效果,windows7更是把拖动做到了极致.其实说起来拖动的实现也很简单,对于有句柄 ...

  8. VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)

    转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件Web ...

  9. MFC中消息响应机制

    由于视类窗口始终覆盖在框架类窗口之上,因此所有操作,包括鼠标单击.鼠标移动等操作都只能由视类窗口捕获.一个MFC消息响应函数在程序中有三处相关信息:函数原型.函数实现和以及用来关联消息和消息响应函数的 ...

随机推荐

  1. JAVA 中 if和while的区别

    while和if本身就用法不同,一个是循环语句,一个是判断语句. if 只做判断,判断一次之后,便不会再回来了while 的话,循环,直到结果为false,才跳出来 链表的结构,要一直读下去,直到读完 ...

  2. Mysql中各种与字符编码集(character_set)有关的变量含义

    mysql涉及到各种字符集,在此做一个总结. 字符集的设置是通过环境变量来设置的,环境变量和linux中的环境变量是一个意思.mysql的环境变量分为两种:session和global.session ...

  3. 基础知识之 - C# Using的用法

    C#里面Using有两种用法: 1.作为指令. using+命名空间,导入其他命名空间中定义的类型,这样可以在程序中直接用命名空间中的类型,不必指定命名空间: 命名空间是.NET程序在逻辑上的组织结构 ...

  4. nyoj 104——最大和——————【子矩阵最大和】

    最大和 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个 ...

  5. TypeScript 入门笔记

    1.原始数据类型 JavaScript 的类型分为两种:原始数据类型和对象数据类型.原始数据类型包括布尔值.数值.字符串.null.undefined 以及 ES6 中的 Symbol. 前五种数据类 ...

  6. rest-framework框架——认证、权限、频率组件

    一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...

  7. js带文字的圆随机运动

    首先是html代码(其实就只有一个画布,记得要把外部js引入写在body底部 <!doctype html> <html> <head> <meta http ...

  8. JS自定义手机端H5键盘

    在输入车牌号的时候,因为很多车牌号都是数字字母混合排列的,所以如果用输入法输入就需要频繁切换数字跟字母,有点麻烦. 在这里我们就用自定义一个弹出框代替键盘来使用. 1.首先,要禁止掉文本框弹出输入法, ...

  9. ASP.NET MVC 音乐商店 - 6. 使用 DataAnnotations 进行模型验证

    在前面的创建专辑与编辑专辑的表单中存在一个问题:我们没有进行任何验证.字段的内容可以不输入,或者在价格的字段中输入一些字符,在执行程序的时候,这些错误会导致数据库保存过程中出现错误,我们将会看到来自数 ...

  10. IT小小鸟读书笔记2

    Part4: 一.    大学的时光真的很容易荒废,自己的实力到头来和自己的成绩单一样空虚,其实自己也是深有同感的. 二.    这个观点我十分的认同:在某个方面比别人多5%的深度,可能拿到的报酬就是 ...