笑落天狼

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

好久没写点东西了,拿点东西凑凑数

实现一个Timer类说起来挺简单,但是如果有特殊的需要时也挺让人头痛的。

我就碰到一个需要在一个对象内部需要聚合多个定时器的需求,而且是真正相应Windows消息的定时器。

需求是BT但是也得想办法实现,想来想去还是Trunk技术实现起来最方便。

我们知道创建一个定时器需要调用一个Windows的Api函数:

UINT_PTR SetTimer(      
    HWND hWnd,
    UINT_PTR nIDEvent,
    UINT uElapse,
    TIMERPROC lpTimerFunc
);

按照MSDN的说法最后一个参数需要传入一个回调函数,格式如下:

VOID CALLBACK TimerProc(      
    HWND hwnd,
    UINT uMsg,
    UINT_PTR idEvent,
    DWORD dwTime
);

我想要达到的目标是,创建每个定时器对象时,分配一个成员函数做为回调函数,当该定时器消息到来时,该成员函数需要相应该消息。

下面说说具体实现,不知道Trunk的可以趁现在去查查资料。

头文件:

 

 1 class ZTimer
 2 {
 3 public:
 4     ZTimer(DWORD Elapse=1000);
 5     virtual ~ZTimer();
 6     VOID    SetElapse(DWORD Elapse);
 7     VOID SetOnTimer(void* pThis,DWORD FunAddr);
 8     VOID Stop();
 9     VOID Start();
10 
11 protected:
12     DWORD    m_Elapse;
13     UINT    m_TimerID;
14 private:
15     BYTE    m_thunk[8+ 2*sizeof(DWORD*)];
16 };
17 

 

 

单元文件:

 

 1     ZTimer::ZTimer(DWORD Elapse)
 2     {
 3         m_Elapse=Elapse;
 4         m_TimerID=0;
 5     }
 6     ZTimer::~ZTimer()
 7     {
 8         Stop();
 9     }
10     VOID    ZTimer::SetElapse(DWORD Elapse)
11     {
12         Stop();
13         m_Elapse=Elapse;
14         m_TimerID=::SetTimer(NULL,0,m_Elapse,(TIMERPROC)&m_thunk[0]);
15     }
16     VOID ZTimer::SetOnTimer(void* pThis,DWORD FunAddr)
17     {
18         DWORD dwDistance = FunAddr - (DWORD) &m_thunk[0- (8+ 2*sizeof(DWORD*));
19         /*           
20           Encoded machine instruction   Equivalent assembly languate notation
21           ---------------------------   -------------------------------------
22           FF 34 24                      push  dword ptr [esp]          ; Save (or duplicate) the Return Addr into stack
23           C7 44 24 04 ?? ?? ?? ??       mov   dword ptr [esp+4], pThis ; Overwite the old Return Addr with 'this pointer'
24           E9 ?? ?? ?? ??                jmp   dwProcPtr                ; Jump to target message handler
25         */
26 
27         m_thunk[7+sizeof(DWORD*)] = 0xE9
28 
29         *((DWORD *&m_thunk[ 0]) = 0x002434FF;
30         *((DWORD *&m_thunk[ 3]) = 0x042444C7;
31         *((DWORD *&m_thunk[ 7]) = (DWORD)(pThis);
32         *((DWORD *&m_thunk[8+sizeof(DWORD*)]) =dwDistance;
33     }
34     VOID ZTimer::Stop()
35     {
36         if (m_TimerID != 0)
37         {
38             ::KillTimer(NULL,m_TimerID);
39             m_TimerID=0;
40         }
41     }
42     VOID ZTimer::Start()
43     {
44         Stop();
45         m_TimerID=::SetTimer(NULL,0,m_Elapse,(TIMERPROC)&m_thunk[0]);
46     }
47 
48 

 

具体使用时:

 

 1 class MyTimerTest
 2 {
 3     ZTimer m_pTimer1;
 4     ZTimer m_pTimer2;
 5 public:
 6     VOID   CALLBACK   OnTimer1(HWND   hwnd,UINT   uMsg,UINT_PTR   idEvent,DWORD   dwTime)
 7     {
 8         printf("Timer1::OnTimer\n");
 9     }
10     VOID   CALLBACK   OnTimer2(HWND   hwnd,UINT   uMsg,UINT_PTR   idEvent,DWORD   dwTime)
11     {
12         printf("Timer2::OnTimer\n");
13     }
14 
15 
16     MyTimerTest()
17     {
18         
19         m_pTimer1.SetOnTimer(this,union_cast<DWORD>(&MyTimerTest::OnTimer1));
20         m_pTimer1.Start();
21         m_pTimer2.SetOnTimer(this,union_cast<DWORD>(&MyTimerTest::OnTimer2));
22         m_pTimer2.Start();
23     }
24     virtual ~MyTimerTest()
25     {
26     }
27 };
28 
29 
30 MyTimerTest timer;
31 
32 
33 
34 int _tmain(int argc, _TCHAR* argv[])
35 {
36     
37 
38     MSG msg;
39     BOOL bRet;
40     while( (bRet = GetMessage( &msg, NULL, 00 )) != 0)
41     { 
42         if (bRet == -1)
43         {
44             break;
45         }
46         else
47         {
48             TranslateMessage(&msg); 
49             DispatchMessage(&msg); 
50         }
51     }
52     
53     return 0;
54 }
55 

 

其中union_cast函数的定义如下:

 

 1 template <class ToType, class FromType>
 2 ToType& union_cast(FromType f)
 3 {
 4     union 
 5     {
 6         FromType _f;
 7         ToType   _t;
 8     }ut;
 9 
10     ut._f = f;
11     return ut._t;
12 }

 

回头看看,有点奇技淫巧的意味。。。算了,不管他抓住耗子就是好猫 !

posted on 2010-02-27 23:40  笑落天狼  阅读(439)  评论(0)    收藏  举报