Listing 1: Callback wrapper example

#include "stdafx.h"
#include "mmsystem.h"

// Callback function prototype
// (from WIN32 SDK)
extern "C"
{
void CALLBACK MyTimerCallBack
(UINT uTimerID,
UINT uMsg,
DWORD dwUser,
DWORD dw1,
DWORD dw2);
}

// pseudo-this bundle structure
typedef struct tagthisInstance
{
DWORD   pseudoThis;
DWORD   dwInstance;
} thisInstance,*LPTHISINSTANCE;


// Timer class
class Ctimer
{
public:
    Ctimer()  {}
    ~Ctimer()
    {
    timeKillEvent(m_id);
    }
    void MySetTimer (UINT uLen);
    void TimerTick(DWORD dwMyData);
private:
    thisInstance   m_ti;
    UINT           m_id;
};


// Function to set a timer
void Ctimer::MySetTimer(UINT uLen)
{
MMRESULT TimerID;
LPTIMECALLBACK lpTimeProc;

m_ti.pseudoThis = (DWORD) this;
m_ti.dwInstance = uLen;

lpTimeProc = &MyTimerCallBack;

TimerID = timeSetEvent(
              uLen,
              uLen/2,
              lpTimeProc,
              (DWORD) &m_ti,
             TIME_PERIODIC);
m_id = (UINT) TimerID;
}

// Tick event handler
// Called by callback wrapper
void Ctimer::TimerTick(DWORD dwMyData)
{
    TRACE("Tick: %d ms", dwMyData);
}
// Callback function
// Unbundles thisInstance and
// calls member function
void CALLBACK MyTimerCallBack
               (UINT uTimerID,
                UINT uMsg,
                DWORD dwUser,
                DWORD dw1,
                DWORD dw2)
{
LPTHISINSTANCE lpti = NULL;
Ctimer  *pseudoThis = NULL;
DWORD    dwData;

// get thisinstance struct
lpti = (LPTHISINSTANCE) dwUser;

// get pseudo this from struct
pseudoThis = (Ctimer *)
       lpti->pseudoThis;

// Get other instance data
dwData = lpti->dwInstance;

//call bound member function
pseudoThis->TimerTick(dwData);
}

//End of File