Click here to Skip to main content
Click here to Skip to main content

CMultimediaTimer - a periodic timer class

, 27 Mar 2002
Rate this:
Please Sign up or sign in to vote.
CMultimediaTimer implements a periodic timer using the Windows Multimedia Timer API
<!-- Download Links --> <!-- Add the rest of your HTML here -->

CMultimediaTimer

CMultimediaTimer implements a simple periodic timer using the Windows Multimedia Timer API.

NB.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 the OnLoop() pure virtual 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 seperate loop handling from the main timer class to prevent calls from within OnLoop() accidently 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

Share

About the Author

John P. Curtis
Web Developer
Australia Australia
John Curtis runs Fatlab Software Pty. Ltd. which provides software services to companies in Perth, Australia and is currently developing a range of productivity apps.
He has 10+ years experience writing C++ software and 3 years writing Java code.
Specialities include STL, Boost, XML, OpenGL, Realtime control, Embedded Linux, Windows CE....

Comments and Discussions

 
BugUnable to Download demo project & source Pinmemberanujack_2111-Nov-13 16:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411023.1 | Last Updated 28 Mar 2002
Article Copyright 2002 by John P. Curtis
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid