CMultimediaTimer - 一个周期性计时器类






4.13/5 (7投票s)
2002年3月28日
1分钟阅读

72195

1675
CMultimediaTimer 使用 Windows Multimedia Timer API 实现周期性计时器
CMultimediaTimer
CMultimediaTimer
使用 Windows 多媒体定时器 API 实现一个简单的周期性定时器。
注意:多媒体定时器实际上是一个独立的高优先级线程,因此所有正常的多线程问题都适用。与工作线程一样,由于 CWinThread
局部存储中存储的句柄映射“魔咒”,不应直接从定时器回调中调用 MFC 对象。
CMultimediaTimer
不依赖于 GUI,因为我用它来处理控制台应用程序中的周期性活动。
要启动定时器
- 从
CMultimediaTimerCallback
派生一个循环处理类,并重写纯虚方法OnLoop()
- 创建一个
CMultimediaTimer
,并将派生循环处理类的实例作为构造函数参数传递。 - 使用循环周期(以毫秒为单位)作为第一个参数调用
Start()
方法。
使用示例:
MyLoopHandlerClass handler;
CMultimediaTimer timer(handler);
timer.Start(20,1); //Run loop at 50Hz with the resolution set to 1ms
类
CMultimediaTimerCallback
是必须重写以支持循环处理的回调接口。
我们将循环处理与主 timer
类分离,以防止从 OnLoop()
内部调用 CMultimediaTimer
方法,这可能会导致竞争条件。
////////////////////////////////////////////////////////////////////////////////////
// CMultimediaTimerCallback - The callback support interface
////////////////////////////////////////////////////////////////////////////////////
class CMultimediaTimerCallback
{
public:
CMultimediaTimerCallback(){}
virtual ~CMultimediaTimerCallback(){}
public:
virtual bool OnLoop()=0; //Must Override timer will stop if return false
virtual void OnStarted(){} //Overrideable called when timer started sucessfully
virtual void OnStopped(){} //Overrideable called after timer stopped
};
CMultimediaTimer
是 timer
类。
要使用,只需从 CMultimediaTimer
派生一个类并重写 OnLoop()
。接下来,使用周期(以毫秒为单位)作为第一个参数调用 Start
方法。
////////////////////////////////////////////////////////////////////////////////////
// CMultimediaTimer - A simple periodic timer
////////////////////////////////////////////////////////////////////////////////////
class CMultimediaTimer
{
public:
CMultimediaTimer(CMultimediaTimerCallback& callback);
virtual ~CMultimediaTimer();
//Start the periodic timer, OnLoop() will be called every nPeriodMs
//milliseconds. Start() returns false if failed and nError returns the error
//code
bool Start(UINT nPeriodMs,
MMRESULT& nError,
UINT nResolutionMs = cDefaultTimerResolution);
//Same as above but no error code returned
bool Start(UINT nPeriodMs,UINT nResolutionMs = cDefaultTimerResolution)
{MMRESULT nErr; return Start(nPeriodMs,nErr,nResolutionMs);}
//Stop the timer
void Stop();
//Is the timer running
bool Active()const {return m_TimerId != 0;}
//Period set while running
UINT GetPeriodMs()const {return m_TimerPeriod;}
//Resolution set while running
UINT GetResolutionMs()const{return m_TimerResolution;}
private:
bool CheckMarker()const;
void ResetPeriodResolution();
void DoLoop();
private:
CMultimediaTimerCallback& m_Callback; //The loop callback
UINT m_TimerPeriod; //Timer period in milliseconds
UINT m_TimerResolution; //Timer resolution in milliseconds
UINT m_TimerId; //ID of timer thread
bool m_EndTimer; //Flag to force timer to stop from loop
FLCriticalSection m_StopCriticalSection; //section to protect multi access
// to Stop()
private:
DWORD m_Marker; //Paranoia check
friend void CALLBACK mmTimerProc(UINT,UINT,DWORD,DWORD,DWORD); //Callback
};
祝您循环愉快!
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。