Trunk技术的一点应用,一个对象可以聚合多个Timer对象的实现

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

实现一个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,  0 0  ))  !=   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  }

 

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

你可能感兴趣的:(Trunk技术的一点应用,一个对象可以聚合多个Timer对象的实现)