MFC- OnIdle空闲处理
CWinApp::OnIdle
virtual BOOL OnIdle( LONG lCount );
返回值:
如果要接收更多的空闲处理时间,则返回非零值;如果不需要更多的空闲时间则返回0。
参数:
lCount 该参数是一个计数值,当应用程序的消息队列为空,OnIdle函数被调用时,该计数值就增加1。
每当一条新消息被处理时,该计数值就被复位为0。你可以使用lCount参数来确定应用程序不处理消息时空闲时间的相对长度。
说明:

重载CWinApp::OnIdle()时,不要忘记要先调用CWinApp::OnIdle()进行MFC默认处理
if (CWinApp::OnIdle(lCount))
return TRUE;
如果忘掉了的话,你会发现一些MFC的UI会出现问题,比如菜单上的选择状态无法更新等问题。
对于一般桌面应用程序中比较少重载这个函数。对于像是视频游戏这一块确有不少用处
如果要执行空闲时处理,则重载这个成员函数。当应用程序的消息队列为空时,OnIdle就在缺省的消息循环中被调用。
你可以用重载函数来调用自己的后台空闲处理任务。
OnIdle应返回0以表明不需要更多的空闲处理时间。
当消息队列为空时,OnIdle每被调用一次lCount参数就增加,而每处理一条新消息lCount就被复位为0。
你可以根据这个计数值调用不同的空闲处理例程。
下面总结了空闲循环处理:
1、如果微软基础类库中的消息循环检查消息队列并发现没有未被处理的消息,它就为应用程序对象调用OnIdle函数,并将lCount参数设为0。
2、OnIdle执行一些处理,然后返回一个非零值,表示它还需要被调用,以进行进一步处理。
3、消息循环再次检查消息队列。如果没有未处理的消息,则再次调用OnIdle,增加lCount参数。
4、最后,OnIdle结束所有的空闲任务并返回0。
这就告诉消息循环停止调用OnIdle直到在消息队列中接收到下一条消息为止,在那时,空闲循环将重新启动,而参数被设为0。
因为只有在OnIdle返回之后应用程序才能处理用户输入,因此在OnIdle中不应进行较长的任务。
注意:
OnIdle的缺省实现更新命令用户接口对象,如菜单项和工具条等,还实现了内部数据结构的清理。
因此,如果你重载了OnIdle,你必须用重载版本中使用的lCount值来调用CWinApp::OnIdle。
首先调用所有基类的空闲处理(即直到基类的OnIdle返回0)。
如果你需要在基类处理完成之前进行一些工作,则应回顾基类的实现以在自己的工作期间选择一个合适的lCount值。
示例:
下面的两个例子演示了OnIdle的用法。
第一个例子处理两个空闲任务,用lCount参数来排列这些任务的优先权。
第一个任务优先权较高,一旦可能你就应当执行此任务。第二个任务不十分重要,只有当用户输入有一个较长时间的间歇的时候才应执行此任务。
注意其中对基类的OnIdle的调用。
第二个例子管理着一组具有不同优先权的空闲任务。
BOOL CMyApp::OnIdle(LONG lCount)
{
BOOL bMore = CWinApp::OnIdle(lCount);
if (lCount == 0)
{
TRACE("App idle for short period of time/n");
bMore = TRUE;
}
else if (lCount == 10)
{
TRACE("App idle for longer amount of time/n");
bMore = TRUE;
}
else if (lCount == 100)
{
TRACE("App idle for even longer amount of time/n");
bMore = TRUE;
}
else if (lCount == 1000)
{
TRACE("App idle for quite a long period of time/n");
// bMore 没有被设为TRUE, 不在需要空闲
// 重要:bMore 没有被设为 FALSE,因为 CWinApp::OnIdle可能还有其它空闲任务要完成。
}
return bMore; // 返回TRUE,只要还有其它空闲任务
}
第二个示例:
// 在这个例子中,有四个空闲循环任务,它们被赋予
// 不同的优先权,运行的机会不同:
// Task1在空闲时总能运行,要求在框架处理它自己的空闲循环任务时没有消息在等候。(lCount为0或1)
// Task2 仅当Task1以及运行时才能运行,要求当Task1运行时没有消息在等候。
// Task3和Task4仅当Task1和Task2都运行之后才能运行,
// 并且在此期间没有消息在等候。如果Task3能够运行,
// 则Task4总是在Task3之后立即运行。
BOOL CMyApp::OnIdle(LONG lCount)
{
// 在这个例子中,像多数应用程序一样,你应该让基类
// 的CWinApp::OnIdle在你试图进行任何附加的空闲循环
// 过程之前完成它的处理。
if (CWinApp::OnIdle(lCount)) return TRUE;
// 基类的CWinApp::OnIdle为lCount保留0和1给框架自己的
// 空闲处理使用。如果你希望与框架平等地共享空闲处理
// 时间,则应替换上面的if语句,直接调用CWinApp::OnIdle,
// 然后为lCount的值0和/或1加入一个case语句。首先应当研
// 究基类的实现以理解你的空闲循环任务将会如何与框架的
// 空闲循环处理竞争。
switch (lCount)
{
case 2:
Task1();
return TRUE; // 下一次给 Task2 一个机会
case 3:
Task2();
return TRUE; // 下一次给Task3和Task4一个机会
case 4:
Task3();
Task4();
return FALSE; // 再次回到空闲循环任务
}
return FALSE;
}
///注意
在VC基于对话框程序中,似乎不能使用OnIdle。从网上查了一下,可以用WM_KICKIDLE消息实现相同功能。WM_KICKIDLE消息响应需要自己手动添加代码。下面是步骤:
1.MyDlg.cpp文件添加包含:
#include <afxpriv.h>
2.MyDlg.h文件添加声明
afx_msg LRESULT OnKickIdle(WPARAM wParam, LPARAM lParam);
3.MyDlg.cpp文件添加消息映射:
ON_MESSAGE(WM_KICKIDLE,OnKickIdle)
4.MyDlg.cpp添加函数的实现:
LRESULT CMyDlg::OnKickIdle(WPARAM wParam, LPARAM lParam)
{
//------TODO--------------------------------
return 0;
}
当没有任何 Windows 消息正在被处理时,框架调用 CWinApp 的成员函数 OnIdle(如“MFC 库参考”中所述)。
重写 OnIdle 以执行后台任务。默认版本更新用户界面对象(如工具栏按钮)的状态,并对框架在操作期间创建的临时对象执行清理工作。下面阐释了在队列中没有任何消息时消息循环调用 OnIdle 的方式。
int CWinThread::Run()
{
.......
for(;;)
{
while (bIdle && //bIdle控制上图的是否有其他空闲任务
!::PeekMessage(&m_msgCur,NULL,NULL,PM_NOREMOVE))
{
if (!OnIdle(lIdleCount++))
{
bIdle = FALSE;
}
}
......//msg loop
}
}
MFC- OnIdle空闲处理的更多相关文章
- 【转】MFC OnIdle的详细说明
转载出处:http://blog.csdn.net/tsing_best/article/details/25055707 CWinApp::OnIdlevirtual BOOL OnIdle( LO ...
- MFC - 微软基础类库和框架
一 MFC的概念和作用 1 什么是MFC?? 全称 Microsoft Foundation Class Library我们称之为微软基础类库 1)从硬盘的存在形式上来说 MFC就是一个库(静/动态库 ...
- 【转载】MFC 程序入口和执行流程
原文链接: http://www.cnblogs.com/liuweilinlin/archive/2012/08/16/2643272.html 一 MFC程序执行过程剖析 1)我们知道在WIN32 ...
- MFC笔记
一.Win32基本程序概念 所有的windows程序都必须载入windows.h MFC程序都有一个Stdafx.h文件,它载入了MFC框架必须的文件. Windows程序以消息为基础,以事件驱动之. ...
- 一个简单的mfc单页界面文件读写程序(MFC 程序入口和执行流程)
参考:MFC 程序入口和执行流程 http://www.cnblogs.com/liuweilinlin/archive/2012/08/16/2643272.html 程序MFCFlie ...
- MFC 程序入口和执行流程
MFC(微软基础类库)以C++类的形式封装了Windows API,给开发者提供了便利,但是初学者常常会疑惑MFC程序的入口在哪里?下面给大家简单介绍一下MFC 程序入口和执行流程. 一 MFC程序执 ...
- MFC程序开始的执行过程详述
1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用程序的窗口函数.而在MFC程 ...
- MFC程序执行过程剖析
一 MFC程序执行过程剖析 1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用 ...
- MFC学习(三)程序入口和执行流程
1) WIN32 API程序当中,程序入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用程序窗口函数.而在MFC程序当中我们 ...
- 【转】MFC 程序入口和执行流程
一 MFC程序执行过程剖析 1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用 ...
随机推荐
- 使用IR2101半桥驱动电机的案例
作为一个电机驱动开发方面的菜鸟,近日研究了一下通过MOS管对整流后的电源斩波用以驱动直流电机进行调速的方案. 在驱动的过程中,遇到了很多问题,当然也有很多的收获. 写下来以供自己将来查阅,也为其他菜鸟 ...
- 怎样創建 iOS 展開式 UITableView?
原文:http://www.appcoda.com.tw/expandable-table-view/ 译者:kmyhy(appcoda的驻站译者) 幾乎全部的 App 都會以導航的方式向用戶展示多個 ...
- Pixhawk---烧写FMU/IO bootloader
Pixhawk-FMU/IO烧写Bootloader 1 说明 用J-link来烧写Bootloader,Pixhawk板FMU/IO接口说明: J-link接口说明: Pix ...
- Linux中的find命令
.递归查找(find 命令 是递归遍历文件夹的) 命令:find . -name “*.txt” //当前路径下递归查找以.txt结尾的文件夹 .不递归查找 find . -name “*.txt” ...
- Android 在Android手机上获取其他应用的包名及版本号
获取Android手机上其他应用的包名及版本号方法有很多,可以通过AAPT从APK包中直接获取,也可以通过代码在手机上获取.显然,对于产品或者用户来说要获取这些信息,在手机上获取更为简便. 下面我们来 ...
- Spring MVC登录注册以及转换json数据
项目结构; 代码如下: BookController package com.mstf.controller; import javax.servlet.http.HttpServletRespons ...
- 【C#Windows 服务】 《二》INI配置文件
一.工具: VS2015+NET Framework4.5. 二.操作: 1.创建INIHelp帮助类 2.丰富帮助类操作 3.windows实例调用 三.代码: 1.INI帮助类: 1 2 3 4 ...
- plt.rcParams[]
plt.rcParams[] pylot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数.通过rc参数可以修改默认的属性,包括窗体大小.每英寸的点数.线条宽度.颜色.样式.坐标轴. ...
- 【IDEA】Error: java: Compliance level '1.6' is incompatible with target level '1.8'. A compliance level '1.8' or better is required解决办法
在运行的时候常常出现如下错误: Error: java: Compliance level '1.6' is incompatible with target level '1.8'. A compl ...
- caioj 1069 动态规划入门(二维一边推2:顺序对齐)(最长公共子序列拓展总结)
caioj 1068是最长公共子序列裸体,秒过, 就不写博客了 caioj 1069到1071 都是最长公共字序列的拓展,我总结出了一个模型,屡试不爽 (1) 字符串下标从1开始,因为0用来表示 ...