Windows95中的定时器的应用

 

Windows95中的定时器的应用



李 振

在windows95 编 程 中 有 时 要 用 到定 时 器 的 功 能, 大 家 常 用 的 是
通 过SetTimer 函 数 设置 一 个 定 时 器, 在 事 件WM_TIMER 响 应 函 数 中
处 理,然 后 用KillTimer 函 数 取 消 此 定 时 器。 但 此 种 方 式 的定 时
器 只 能 精 确 到 大 约55 毫 秒, 对 于55 毫 秒 以 下的 时 间 精 度 便 无
能 为 力。

笔 者 在 这 里 向 大 家 提 供 一个 可 以 精 确 到1 毫 秒 的 定 时 器 — —
多 媒 体 定 时器。 它 主 要 通 过 以 下 函 数 来 实 现:

timeBeginPeriod — — 建 立 应 用 程序 使 用 的 定 时 器 分 辨 率;

timeEndPeriod — — 清 除 前 面 用timeBeginPeriod 函 数 建 立 的 最 小 定
时 器 分 辨 率;

timeSetEvent — — 产 生 一 个 在 指定 的 时 间 或 时 间 周 期 间 隔 内
执 行 的 定 时 器 事件;

timeKillEvent — — 删 除 前 面 用timeSetEvent 产 生 的 定 时 器 事 件;

timeGetDevCaps — — 返 回 关 于 定时 器 服 务 能 力 的 信 息。

下 面 就 结 合 一 段 程 序 来 具体 说 明 它 的 用 法。 这 段 程 序 的 主
要 功 能 是: 设置 两 个 时 钟 定 时 器, 一 个 间 隔 是1 毫 秒, 一 个
间隔 是2 秒, 每 执 行 一 次, 输 出 当 前 系 统 时 钟 值 到文 件“cure.out”,
以 比 较 此 定 时 器 的 精 确 度。( 此程 序 在 中 文windows95 及
Microsoft VC5.0 编 译 通 过。 只 节 取与 定 时 器 有 关 的 部 分 程 序。)

#include < stdio.h >
//包含所用系统函数的头文件,
如果编译有问题,可调整此语句的位置
#include < mmsystem.h >

//定义1毫秒和2秒时钟间隔,以毫秒为单位
#define ONE_MILLI_SECOND1
#define TWO_SECOND 2000
//定义时钟分辨率,以毫秒为单位
#define TIMER_ACCURACY1

UINT wTimerRes_1ms,wTimerRes_2s;  //定义时间间隔
UINT wAccuracy;//定义分辨率
UINT TimerID_1ms,TimerID_2s;//定义定时器句柄

CCureApp::CCureApp()
: fout("cure.out", ios::out)//打开输出文件“cure.out”
{
// TODO: add construction code here,
// Place all significant
       initialization in InitInstance
//给时间间隔变量赋值
wTimerRes_1ms = ONE_MILLI_SECOND ;
wTimerRes_2s = TWO_SECOND;

TIMECAPS tc;
//通过函数timeGetDevCaps取出系统
的分辨率取值范围(对intel系统,
1~16毫秒),//如果无错则继续
if(timeGetDevCaps(&tc, sizeof(TIMECAPS))
== TIMERR_NOERROR)
{
//分辨率的值不能超出系统的取值范围
wAccuracy = min(max(tc.wPeriodMin,
TIMER_ACCURACY),tc.wPeriodMax);
//调用timeBeginPeriod函数设置定时器
的分辨率,类似于for循环的步长
timeBeginPeriod(wAccuracy);
//设置定时器
InitializeTimer();
}
}

CCureApp::~CCureApp()
{
//结束时钟
fout < <  "结束时钟" < <  endl;
//删除两个定时器
timeKillEvent(TimerID_1ms);
timeKillEvent(TimerID_2s);
//删除设置的分辨率
timeEndPeriod(wAccuracy);
}
注:使用完的定时器及分辨率一定
要删除,否则系统会越来越慢。

void CCureApp::InitializeTimer()
{
StartOneMilliSecondTimer();
StartTwoSecondTimer();
}

//一毫秒定时器的回调函数,
类似于中断处理程序
voidPASCAL//一定要声明为全局PASCAL函数,
否则编译会有问题
OneMilliSecondProc(UINT wTimerID, UINT msg,
DWORD dwUser, DWORD dw1, DWORD dw2)
{
static int ms = 0;//定义计数器
CCureApp *app = (CCureApp *)dwUser;
//取得系统时间以毫秒为单位
DWORD osBinaryTime = GetTickCount();
//输出计数器值和当前系统时间到文件
app- >fout < <  ++ms < <  ": 1ms : "
< <  osBinaryTime < <  endl;
}

//加装1毫秒定时器
void CCureApp::StartOneMilliSecondTimer()
{
if((TimerID_1ms = timeSetEvent(wTimerRes_1ms, wAccuracy,
(LPTIMECALLBACK) OneMilliSecondProc,//回调函数
(DWORD)this,//用户自传送到回调函数的数据
/*周期调用,只使用一次用TIME_ONESHOT*/
TIME_PERIODIC)) == 0)
{
AfxMessageBox("不能计时", MB_OK | MB_ICONASTERISK);
}
else//不等于0表明加装成功,
返回此定时器的句柄
fout < <  "16ms计时:" < <  endl;
}

以下为2秒定时器的回调函
数和加装函数,与1毫秒的类似;
void PASCAL
TwoSecondProc(UINT wTimerID, UINT msg,
  DWORD dwUser, DWORD dw1, DWORD dw2)
{
static int s = 0;
CCureApp *app = (CCureApp *)dwUser;
DWORD osBinaryTime = GetTickCount();
app- >fout < <  "***********************
***********************" < <  endl;
app- >fout < <  ++s < <  ": 2s : "
< <  osBinaryTime < <  endl;
}

void CCureApp::StartTwoSecondTimer()
{
if((TimerID_2s = timeSetEvent(wTimerRes_2s, wAccuracy,
(LPTIMECALLBACK) TwoSecondProc,
(DWORD)this,
  TIME_PERIODIC)) == 0)
{
AfxMessageBox("不能计时", MB_OK | MB_ICONASTERISK);
}
else
fout < <  "2s计时:" < <  endl;
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值