timeSetEvent timeKillEvent 实现较精确定时
来源:互联网 发布:西安交大网络教育招生 编辑:程序博客网 时间:2024/04/30 14:28
1、MOUDLE.abs 文件
Public lTimeID As Integer
Public lTimeID2 As Integer
Public Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
Public Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
Public Declare Function timeSetEvent Lib "winmm.dll" (ByVal uDelay As Long, ByVal uResolution As Long, ByVal lpFunction As Long, ByVal dwUser As Long, ByVal uFlags As Long) As Long
Public Declare Function timeKillEvent Lib "winmm.dll" (ByVal uID As Long) As Long
Public Declare Function GetTickCount Lib "kernel32" () As Long 2、创建定时器
private sub form1_click()
lTimeID2 = timeSetEvent(1000, 0, AddressOf TimeProcScan, 1, 1)
If lTimeID2 = 0 Then
MsgBox "cannot excute timesetevent2"
End If
lTimeID = timeSetEvent(100, 0, AddressOf TimeProcAcq, 1, 1)
If lTimeID = 0 Then
MsgBox "cannot excute timesetevent"
End If
end sub
3、定义回调函数(在MOUDLE.ABS中定义) Public Function
TimeProcAcq(ByVal uID As Long, ByVal uMsg As Long, ByVal dwUser As Long, ByVal dw1 As Long, ByVal dw2 As Long)
end Function Public Function TimeProcScan(ByVal uID As Long, ByVal uMsg As Long, ByVal dwUser As Long, ByVal dw1 As Long, ByVal dw2 As Long)
end Function
4、删除进程(一定要在程序退出之前删除)
Private Sub Form_Unload(Cancel As Integer)
If lTimeID Then
timeKillEvent (lTimeID)
End If
If lTimeID2 Then
timeKillEvent (lTimeID2)
End If
End
End Sub
5、注:
1 )、timeSetEvent的原形如下:
MMRESULT timeSetEvent(
UINT uDelay,
UINT uResolution,
LPTIMECALLBACK lpTimeProc,
DWORD_PTR dwUser,
UINT fuEvent
);
uDelay
延时时间
uResolution
误差允许值,如果该值设置为0,则定时器将分毫不差的进行计时,当然,代价是大的开销;一般在程序允许的范围内不妨设置几毫秒的偏差。 LPTIMECALLBACK 是函数指针,指向你的自己的回调函数。
dwUser 用户自己要传给回调函数的参数。
fuEvent 说明定时器特性的其他参数,具体如下:
常量 值 说明
TIME_ONESHOT 0 指在预定时间上执行一次,这时就相当于Sleep了一段时间。。
TIME_PERIODIC 1 周期性执行回调函数。
该函数返回值就是你的timer的标识(uID)
2)、 MMRESULT timeKillEvent(UNIT uID)
uID是你开始timeSetEvent得到的timer标识(uID)。
注:这个很重要,必须在用完后用该函数杀掉timer,因为这个时钟机制不同于Win32系统API里的时钟设置,它是为了多媒体单独设计的,单独起了一个线程,附加到你的程序进程上。当应用程序退出时,个新的线程不会被正常终止,可能会地址冲突。
VC中
在VC编程中,用SetTimer可以定义一个定时器,到时间了,就响应OnTimer消息,但这种定时器精度太低了。如果需要精度更高一些的定时器(精确到1ms),可以使用下面的高精度多媒体定时器进行代码优化,可以达到毫秒级的精度,而且使用方便。先要包含头文件"mmsystem.h"和库文件"winmm.lib"。
源代码
#include "mmsystem.h" //head file
#pragma comment(lib,"winmm") //lib file
const int timePeriod = 2;
const int timeRes = 1 ;
UINT CMyTimer::CreateTimer()
{
//create the timer
// Create a periodic timer
timeBeginPeriod(timeRes);
timerID = timeSetEvent(
timePeriod,
timeRes,
TimerHandler,
(DWORD)this,
TIME_PERIODIC);
return timerID;
}
void CMyTimer::DestroyTimer()
{
if ( bRun )
{
timeKillEvent(timerID);
timeEndPeriod(timeRes);
bRun = FALSE;
}
}
void CALLBACK CMyTimer::TimerHandler(UINT id, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
CMyTimer* pThis = (CMyTimer*)dwUser;
}
使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。函数的原型如下:
MMRESULT timeSetEvent( UINT uDelay,
UINT uResolution,