CMultimediaTimer - A Periodic Timer Class






4.13/5 (7 votes)
Mar 28, 2002
1 min read

71722

1656
CMultimediaTimer implements a periodic timer using the Windows Multimedia Timer API
CMultimediaTimer
CMultimediaTimer
implements a simple periodic timer using the Windows Multimedia Timer API.
N.B.: A Multimedia timer is actually a seperate high priority thread so all the normal multithreading issues apply. As with worker threads, MFC objects should not be called directly from a timer callback due to the Handle Map hoodoo stored in the CWinThread
local storage.
CMultimediaTimer
is not GUI specific as I use it to handle periodic activity in console applications.
To start a timer:
- Derive a loop handler class from
CMultimediaTimerCallback
overiding theOnLoop()
purevirtual
method - Create a
CMultimediaTimer
passing an instance of the derived loop handling class as the constructor parameter - Call the
Start()
method with the loop period in milliseconds as the first parameter.
Usage example:
MyLoopHandlerClass handler;
CMultimediaTimer timer(handler);
timer.Start(20,1); //Run loop at 50Hz with the resolution set to 1ms
Classes
CMultimediaTimerCallback
is the callback interface that must be overidden to support loop handling.
We separate loop handling from the main timer
class to prevent calls from within OnLoop()
accidentally calling CMultimediaTimer
methods which could cause a race condition.
////////////////////////////////////////////////////////////////////////////////////
// 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
is the timer
class.
To use, simply derive a class from CMultimediaTimer
and override OnLoop()
. Next, call the Start
method with the period in milliseconds as the first parameter.
////////////////////////////////////////////////////////////////////////////////////
// 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
};
Happy looping!
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.