How do I convert a member function pointer to the TIMERPROC type for use with the WINAPI SetTimer?  The code snippet below shows how I'm doing it now, but when I compile I get this error:
error C2664: 'SetTimer' : cannot convert parameter 4 from 'void (__stdcall CBuildAndSend::* )(HWND,UINT,UINT_PTR,DWORD)' to 'TIMERPROC'
The callback needs to be tied to its originating class instance. If there is a better way to do that, I'm all ears. Thanks.
class CMyClass
{
public:
    void (CALLBACK CBuildAndSend::*TimerCbfn)( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime );
private:
    void CALLBACK TimeoutTimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime );
};
CMyClass::CMyClass()
{
    ...
    this->TimerCbfn = &CBuildAndSend::TimeoutTimerProc;
    ...
    ::CreateThread(
        NULL,                           // no security attributes
        0,                              // use default initial stack size
        reinterpret_cast<LPTHREAD_START_ROUTINE>(BasThreadFn), // function to execute in new thread
        this,                           // thread parameters
        0,                              // use default creation settings
        NULL                            // thread ID is not needed
        )
}
void CALLBACK CMyClass::TimeoutTimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
    ...
}
static DWORD MyThreadFn( LPVOID pParam )
{
    CMyClass * pMyClass = (CMyClass *)pParam;
    ...
    ::SetTimer( NULL, 0, BAS_DEFAULT_TIMEOUT, pMyClass->TimerCbfn ); // <-- Error Here
    ...
}
                Member-function and TIMEPROC are not compatible types.
You need to make the member function static. Then it will work, assuming parameter-list is same in both, static member  function and TIMEPROC.
class CMyClass
{
public:
    //modified
    void (CALLBACK *TimerCbfn)(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
private:
    //modified
    static void CALLBACK TimeoutTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime );
};
Function pointer as well as member function both are modified. Now it should work.
Now since the callback function became static, it cannot access the non-static members of the class, because you don't have this pointer in the function.
To access the non-static members, you can do this:
class CMyClass
{
public:
    static void CALLBACK TimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime );
    //add this static member
    static std::map<UINT_PTR, CMyClass*> m_CMyClassMap; //declaration
};
//this should go in the  CMyClass.cpp file
std::map<UINT_PTR, CMyClass*> CMyClass::m_CMyClassMap;  //definition
static DWORD MyThreadFn( LPVOID pParam )
{
    CMyClass * pMyClass = (CMyClass *)pParam;
    UINT_PTR id = ::SetTimer( NULL, 0, BAS_DEFAULT_TIMEOUT, CMyClass::TimerProc);
    //store the class instance with the id as key!        
    m_CMyClassMap[id]= pMyClass; 
}
void CALLBACK CMyClass::TimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
    //retrieve the class instance
    CMyClass *pMyClass= m_CMyClassMap[idEvent];
    /*
      now using pMyClass, you can access the non-static 
      members of the class. e.g
      pMyClass->NonStaticMemberFunction();
    */
}
I removed TimerCbfn from my implementation, as it doesn't really needed. You can pass TimerProc directly to SetTimer as last  argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With