VC中加入定时机制的几种方法

定时机制是指在程序运行当中间隔特定的时间引发指定的事件。在DOS下编程时,主要依靠时钟中断Int 8及其调用中断 Int 1cH来实现,应用程序通过修改这些系统中断来达到实现定时触发。而在Windows下,若想象在DOS下肆无忌惮的修改系统是不现实的,那么应当如何实现定时机制呢?下面在下就在学习当中的几点体会谈谈这个问题,提出几种方案供大家参考。

第一种方案是大家熟悉的截获定时消息的途径。在Windows提供给我们使用的系统资源当中,有一种称为“定时器(Timer)”的特殊资源,在申请了这类资源的程序当中每间隔一段时间会接收到值为WM_TIMER的消息。需要定时执行的代码可以放在该消息的处理部分。如果在VC中,我们可以具体按照以下步骤实现这一目的:

利用MFC AppWizard创建一个标准的工程,接受所有缺省选项。名为s1

在Classview中选中“CMainFrame”类,然后按Ctrl+W激活ClassWizard,在“Message Map”选项卡中Class Name选“CMainFrame”,接着在“Message”中选“WM_TIMER”,最后按下“Add Funcation”。以上步骤加入了对WM_TIMER消息的映射处理。

回到Classview中,双击“OnCreate”成员函数,在函数的末尾添加申请Timer的语句:
SetTimer(100,1000,NULL);//申请一个标识值为100的Timer,定时间隔为1000毫秒(1秒)。

在“Classview”中双击OnTimer函数,输入要定时实现的代码。本例子中为:
MessageBeep(1000);;//每隔一秒发出通告声

编译并执行之,我们可以每隔一秒就听到声音。这正是我们在OnTimer函数内要求执行的。

实际当中,我们可以将“MessageBeep(1000);”换成任何我们想完成的任务,譬如定时存盘等。

第二种方案也利用Timer资源,但却是采用已经编写好的代码我们可以加入一个具有定时功能的组件至当前工程当中。这种方法特别适用于基于对话框的工程。具体步骤如下:

利用MFC AppWizard创建一个基于对话框的工程,其余接受所有缺省选项。名为s2。

在ResourceView中,双击IDD_S2_DIALOG,显示对话框,将其中的“To do:”改为“定时触发演示的例子”,表明工程的作用。

右击对话框编辑区,在弹出的右键菜单中选择“Insert ActiveX Control”,从弹出的列表框中选择“Timer Object”,确定后会在对话框内出现一个Timer对象。

我们右击Timer对象,从弹出的菜单中选择“Properties”,接着选“All”选项卡,将其中的Interval值设为5000,即每隔5秒发生一次Timer事件。

回到对话框编辑界面,双击Timer,产生一个CS2Dlg::OnTimerTimer1成员函数,接受缺省值,并在函数实现部分输入:
MessageBox("定时触发消息框","定时演示" ,MB_OK);

编译并运行此工程,将会在产生的对话框运行期间,每隔5秒弹出一个消息框。

同样,我们可以以任何自己的代码来替换5中的消息框语句。详细见附例s2。

第三种方法是采用线程技术。众所周知,Windows 9X是一个基于多线程的多任务操作系统,在内核中以线程作为调度的基本单位,由系统分时间片进行调度。利用这一点,我们可以在程序当中创建一个“司职”计时的线程,通过线程间的同步来定时触发我们要完成的任务的代码。不象前两种方法需要至少有一个窗口作为接受消息的主窗口,采用线程技术实现定时触发将免去创建窗口的麻烦以及带来的系统各种资源的消耗。下面我们来举一个例子来说明这个问题:我们在CmyApp类的Initstance成员中不建立主窗口而是创建一个工作线程,该线程休眠一定的时间后,自动调用主线程的SomeThing函数。为了支持线程的运行,我们需要给CmyApp类增加相应的线程函数。下面,我们还是一步一步的实现:

利用MFC AppWizard创建一个标准工程,其中为不产生多余的代码,不选文档/视图支持,并选择单文档。工程名为S3。

在CS3App:: InitInstance()中用“/* … */”注释掉“return TRUE;”之前的所有代码。这是为了不建立窗口。并添加以下代码:
ExitFlag=TRUE;//是否结束主线程的循环的标志变量。因为子线程严重依赖主线程,所以在本例子中为了避免没有主窗口而提前结束应用程序,从而使子线程无法存在,所以给主线程一个循环,知道全局变量ExitFlag在子线程退出前被设置成FALSE为止.
StartThread();//启动线程
do{}while(ExitFlag);//直到结束子线程
::MessageBox(NULL,"主线程结束!","定时触发演示",MB_OK);
return TRUE;

在Globals中增加一标志变量“ExitFlag”,类型为BOOL。它被主线程用来判断是否结束自身运行。

通过ClassView在CS3App的Public部分声明以下函数:
void StartThread(void); //启动线程
static UINT ThreadFunction(void); //主要执行代码的函数
static UINT StaticThreadFunc(LPVOID lpparam);//设置线程时用到的函数
需要特别指出的是,用AfxBeginThread进行线程设置时,第一参数必须象本例所指出的那样声明为Static ,不然参数转换的错误会扰得你不得安宁。

在StartThread中输入如下代码:
AfxBeginThread(StaticThreadFunc,this);//建立并启动线程

在StaticThreadFunc中输入如下代码:
return ThreadFunc();//调用完成主要线程代码的函数,注意一定要是Static.

实现ThreadFunction:
int i;
i=5;//触发5次
while(i--)
{
Sleep(5000);//间隔5秒
::MessageBox (NULL,"我被定时触发了!","定时触发演示",MB_OK);
}
ExitFlag=FALSE;//ExitFlag是一全局变量,通知主线程结束运行。
return 0; 
}

编译并运行工程,将看不到应用程序窗口,但可以看到每隔5秒,桌面上出现一个消息框,5次后弹出主线程结束的消息框。

以上即本人在学习当中解决 Windows下实现定时触发而采取的一些办法,各自方法的特点也在介绍当中指出。希望所述能给大家一点帮助,更希望能得到大家的指正。如果您有什么意见和设想,欢迎发E-Mail给我(yangshanhe@21cn.com)。

 

==

很早之前2000年的拙作,集在一起,免得自己都不清楚干过什么。

时间: 2024-08-31 06:40:35

VC中加入定时机制的几种方法的相关文章

Oracle中获取执行计划的几种方法分析

以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下   1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语句前加explain plan for,此时将生成的执行计划存储到计划表中,语句如下: explain plan for SQL语句然后,在计划表中查询刚刚生成的执行计划,语句如下: select * from table(

百度搜索研发部:索引页链接补全机制的一种方法

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 索引页链接补全机制的一种方法 一.背景 Spider位于搜索引擎数据流的最上游,负责将互联网上的资源采集到本地,提供给后续检索使用,是搜索引擎的最主要数据来源之一.spider系统的目标就是发现并抓取互联网中一切有价值的网页,为达到这个目标,首先就是发现有价值网页的链接,当前spider有多种链接发现机制来尽量快而全的发现资源链接,本文主要描

Word中输入立方米符号的三种方法

  Word中输入立方米符号的三种方法         Word中输入立方米符号方法一:输入法输入 其实现在有些输入法中集成了很多特殊符号,例如搜狗拼音中就有立方米符号,我们只需要打出立方米的拼音,就会出现一个立方米符号的选项. Word中输入立方米符号方法二:利用制作上标的方法 用制作上标的方法可以做出立方米符号的效果,但这种方法其实还可以细分为几种不同的操作,下面一一进行介绍. 一.在Word文档中输入3,然后将其选中,切换到"开始"选项卡,单击"上标"按钮即可

在Word文档中插入Cad图的3种方法

在word文件中插入我们绘制的cad图,方法大体上有三种,但是它们达到的效果却并不相同,有的显得精致些,有的显得粗糙些,根据我们写作的目的还要进行相应的再处理,这个过程有一些技巧,现在把它写下来,希望能给读者朋友以启发. 要在word文件中插入一个cad图,可以利用下面的三种方法来实现: 第一种,利用键盘上的"print screen sysrq"来抓取cad图,再通过系统自带的画图软件做进一步的修剪,去掉cad剪贴图中多余的部分,这项工作为了是能使图片在word文件中显示的足够的清晰

Flash中实现物体运动的三种方法

现在用Flash开发的游戏是越来越多了.很多朋友也很想学习用Flash制作游戏的方法.大家知道,不管在什么游戏中,实现物体的运动是游戏的前提,而不同的游戏里物体移动的方式又不尽相同.所以,想学习制作Flash游戏的朋友今天就先随我一起学学在Flash中实现物体运动的几种方法吧.几种方法如下: 方法一:通过单击按钮实现物体的单位运动 这种方法一般在需要按键的游戏中使用.你也可以给某个实体加上这段代码,然后通过单击这个实体达到某种游戏效果. 1.打开Flash,按快捷键"Ctrl + M"

实用技巧:PHP中调用Java类的两种方法

Java语言功能强大,因此在许多情况下在php中来调用Java的功能将十分有用.在php中调用Java语言有两种方法,一种是使用php中的Java扩展模块,另一种是使用minij2ee应用服务器提供的SJOP协议实现.下面我们来比较一下这两种方法各自的特点. 1.php的Java模块 php发布版中包含一个Java扩展模块,可以用来调用Java对象,例如: <?php$system=new Java("java.lang.System");print "Java ver

在VB中调用CHM 帮助的几种方法

在VB中调用CHM 帮助的几种方法 一个应用程序不论编制得如何完美,在很多情况下用户还是会对如何使用它提出问题. Visual Basic 提供了对两种不同帮助系统的支持:传统的 Windows 帮助系统 (WinHelp)和新的 HTML 帮助(CHM帮助).当我们制作好帮助文件后,就需要在程序的适当位置编写代码进行调用,本文将讨论几种在程序中调用CHM帮助文件的方法. 方法一 使用F1键:这种方法最简单,只需如下代码即可:Private Sub Form_Load() App.HelpFil

Excel中合并单元格的几种方法及合并单元格快捷键

  Excel中合并单元格的几种方法及合并单元格快捷键          如下图所示,希望将A1到E1,这之间所有单元格合并成一个大单元格操作方法如下: 合并单元格方法一:利用格式菜单上的"合并及居中"按钮合并单元格 ①首先,选中A1.B1.C1.D1.E1这些单元格; ②然后单击"格式"工具栏上面的"合并及居中"按钮; 此时,这几个单元格就已经合并成了一个大单元格了,是不是很简单呀. 合并单元格方法二:利用"设置单元格格式"

jsp页面中插入css样式的三种方法总结

 本篇文章主要是对jsp页面中插入css样式的三种方法进行了总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 1. 外部样式   当样式需要应用于很多页面时,外部样式表将是理想的选择.在使用外部样式表的情况下,你可以通过改变一个文件来改变整个站点的外观.每个页面使用<link>标签链接到样式表.<link>标签在(文档的)头部:   <head> <link rel="stylesheet"  type="text/css&qu