使用SetTimer传递用户数据 [英] Passing User Data with SetTimer

查看:123
本文介绍了使用SetTimer传递用户数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在类的函数中调用SetTimer。

  SetTimer(NULL,0,10000,(TIMERPROC)TimerCallBack); 

其中TimerCallBack是:

  static VOID CALLBACK TimerCallBack(HWND,UINT,UINT,DWORD)



我需要调用启动定时器的类的方法之一,因为TimerCallBack是静态的,它不能再访问类对象了。



我找不到任何方法传递对象指针以及SetTimer,以便我可以在回调函数上接收它。



有没有其他方法来实现这一点,如果它不支持使用SetTimer其他方式我可以实现这个。

解决方案

很明显,如果你在一个窗口中引导定时器消息,你只需将用户数据存储在窗口中。 p>

使用TimerProc的唯一方法是创建一个类,用于管理timer-id到用户数据对象的静态作用域映射。



这样的东西(因为这是一个c ++问题,我只是实现一个快速和脏的函子类型的东西,使TimerMgr可以安排回调直接给类的成员,这通常是为什么你试图存储用户数据:

  // Timer.h 
#include< map>
class CTimer {
public:
class Callback {
public:
virtual void operator()(DWORD dwTime)= 0;
};
template< class T>
class ClassCallback:public Callback {
T * _classPtr;
typedef void(T :: * fnTimer)(DWORD dwTime);
fnTimer _timerProc;
public:
ClassCallback(T * classPtr,fnTimer timerProc):_ classPtr(classPtr),_ timerProc(timerProc){}
virtual void operator()(DWORD dwTime){
(_classPtr-> * _ timerProc) dwTime);
}
};

static void AddTimer(Callback * timerObj,DWORD interval){
UINT_PTR id = SetTimer(NULL,0,interval,TimerProc);
//使用id作为键将映射添加到映射
_timers [id] = timerObj;
}
static void CALLBACK TimerProc(HWND hwnd,UINT msg,UINT_PTR timerId,DWORD dwTime){
_timers [timerId] - > operator()(dwTime);
}
private:
static std :: map< UINT_PTR,Callback *> _timers;
};

//在Timer.cpp中
#include< windows.h>
#include< Timer.h>
std :: map< UINT_PTR,CTimer :: Callback *> CTimer :: _ timers;

//在SomeOtherClass.cpp
类CSomeClass {
void OnTimer1(DWORD dwTime){
}
public:
void DoTimerStuff ){
CTimer :: AddTimer(new CTimer :: ClassCallback< CSomeClass>(this,& CSomeClass :: OnTimer1),100);
}
};

从地图中删除计时器将作为练习留给读者:)







  • ClassCallback需要继承回调。

  • 需要定义静态变量

  • 代码现在可以在MSVC 9.0上正确构建和运行


I am calling SetTimer in a function of a Class.

SetTimer(NULL, 0, 10000, (TIMERPROC) TimerCallBack);  

Where TimerCallBack is:

static VOID CALLBACK TimerCallBack(HWND, UINT, UINT, DWORD)

Now my need is to call one of the method of class which initiated timer, since TimerCallBack is static it has no access to the class object anymore.

I cant find any way to pass object pointer along with the SetTimer so that I can receive it back on Callback function.

Is there any other way to achieve this, if its not supported using SetTimer then which other way I can implement this.

解决方案

Obviously, if you were directing timer messages at a window, you could just store the user data with the window.

The only way to do this with a TimerProc is to make a class that manages a statically scoped map of timer-id's to user data objects.

Something like this (As this is a c++ question, Im just implementing a quick and dirty functor type thing so that the TimerMgr can arrange callbacks directly to members of classes, which is usually why you are trying to store user data:

// Timer.h
#include <map>
class CTimer {
public:
  class Callback {
  public:
    virtual void operator()(DWORD dwTime)=0;
  };
  template<class T>
  class ClassCallback : public Callback {
    T* _classPtr;
    typedef void(T::*fnTimer)(DWORD dwTime);
    fnTimer _timerProc;
  public:
    ClassCallback(T* classPtr,fnTimer timerProc):_classPtr(classPtr),_timerProc(timerProc){}
    virtual void operator()(DWORD dwTime){
      (_classPtr->*_timerProc)(dwTime);
    }
  };

  static void AddTimer(Callback* timerObj, DWORD interval){
    UINT_PTR id = SetTimer(NULL,0,interval,TimerProc);
    // add the timer to the map using the id as the key
    _timers[id] = timerObj;
  }
  static void CALLBACK TimerProc(HWND hwnd,UINT msg,UINT_PTR timerId,DWORD dwTime){
    _timers[timerId]->operator()(dwTime);
  }
private:
  static std::map<UINT_PTR, Callback*> _timers;
};

// In Timer.cpp
#include <windows.h>
#include <Timer.h>
std::map<UINT_PTR,CTimer::Callback*> CTimer::_timers;

// In SomeOtherClass.cpp
class CSomeClass {
  void OnTimer1(DWORD dwTime){
  }
public:
  void DoTimerStuff(){
    CTimer::AddTimer( new CTimer::ClassCallback<CSomeClass>(this,&CSomeClass::OnTimer1), 100);
  }
};

Removing timers from the map is left as an exercise for the reader :)


  • ClassCallback needed to inherit Callback.
  • static variables need to be defined
  • Code now builds and runs correctly on MSVC 9.0

这篇关于使用SetTimer传递用户数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆