Listing 1: Penton's callback technique

// callback.cpp : example of using a template
//                object to simplify calling
//                class member functions from
//                'C' callback API's
//
/////////////////////////////////////////////
     
#include <windows.h>
#include <iostream.h>
#include <process.h>
     
// define a template class for timer callbacks
     
template <class T>
class timer_callback {
     
public:
     
   typedef void (T::* Tpmf)();
      // a useful typedef for pointers to member
      // variables
     
   timer_callback() { }
      // constructor
     
   ~timer_callback() { }
      // destructor
     
   MMRESULT create(
      T *      pobj,
      Tpmf     pmf,
      UINT     delay,
      UINT     resolution
   )
      // create a timer callback
      // called with a pointer to the instance
      // of the class and
      // a pointer to the relevant member
      // function for the callback.
   {
      // remember the class instance
      _pobj = pobj;
      _pmf = pmf;
      _delay = delay;
      _resolution = resolution;
     
      // create a timer event
      _timer_id = timeSetEvent(
         _delay, _resolution,
         timer_callback_stub, (DWORD)this,
         TIME_PERIODIC);
      return _timer_id;
   }
     
   static void __stdcall timer_callback_stub(
      UINT  timer_id,
      UINT  msg,
      DWORD user,
      DWORD dw1,
      DWORD dw2
   )
   {
      // get back the pointer to the
      // callback object 
      timer_callback * p =
        (timer_callback *)user;
     
      // call the member function
      ((p->_pobj)->*(p->_pmf))();
   }
     
   UINT delay() const
      // get the timer delay
   {
      return _delay;
   }
     
     
private:
     
   T *      _pobj;        // pointer to object
                         // instance 
   Tpmf     _pmf;         // pointer to member
                         // function 
   UINT     _timer_id;    // timer identifier
   UINT     _delay;       // timer delay
   UINT     _resolution;  // timer resolution
     
};
     
// example class using the timer_callback template
     
class myobject {
     
public:
     
   myobject()
   {
      // create the timer event
      _t1.create(this, timer1, 1000, 500); 
      _t2.create(this, timer2, 500, 250);
   }
      // constructor
     
   ~myobject() { }
      // destructor
     
   void timer1()
      // react to timer callback
   {
      cout << "Tick 1: " << _t1.delay()
           << " ms" << endl;
   }
     
   void timer2()
      // react to timer callback
   {
      cout << "Tick 2: " << _t2.delay()
           << " ms" << endl;
   }
     
private:
     
   timer_callback<myobject>   _t1; // callbk obj 
   timer_callback<myobject>   _t2; // callbk obj
     
};
     
int main()
{
   // create an object with a timer callback 
   myobject o;
     
//
// do application stuff . . .
//
   Sleep(10000);
     
   return 0;
}
//End of File