基于委托机制的定时器的实现
来源:互联网 发布:单管放大电路实验数据 编辑:程序博客网 时间:2024/06/04 18:33
最近在做Win32开发,要用到多个定时器,由于需要用定时器的对象没有窗口,又不想恶心地先传到窗口再让窗口传给自己,就看看MSDN有没有更好的办法:
下面摘抄MSDN声明部分,原文参考http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx
SetTimer function
UINT_PTR WINAPI SetTimer(
__in_opt HWND hWnd,
__in UINT_PTR nIDEvent,
__in UINT uElapse,
__in_opt TIMERPROC lpTimerFunc
);
看了看后面的参数解析,大意是,如果hWnd传一个NULL进去,系统将通过回调函数通知,就是最后一个参数了,并且,此时 nIDEvent也应该为NULL。
然后再参考TimerProc:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644907(v=vs.85).aspx
TimerProc
VOID CALLBACK TimerProc(
__in HWND hwnd,
__in UINT uMsg,
__in UINT_PTR idEvent,
__in DWORD dwTime
);
如果SetTimer时第一个参数传了NULL,这里对我们而言,hwnd == NULL 常数,uMsg == WM_TIMER,常数,idEvent是SetTimer返回值,有用,dwTime是GetTickCount 得到,意义也不大。并且这里完全无法存放自己的附加数据。于是想到了封装。下面看代码:
//Timer.h#ifndef Timer_h__#define Timer_h__#include <windows.h>#pragma warning(disable:4786)#include <MAP>class CTimer;class CTimerDelegate{public:virtual void OnTimer(CTimer *pTimer,LPVOID lParam) = 0;};typedef std::map<UINT,CTimer*> TIMER_MAP;typedef std::pair<UINT,CTimer*> TIMER_PAIR;class CTimer{private:CTimerDelegate*m_pDelegate;LPVOIDm_lTimerParam;UINTm_nTimerID;private:CTimer(CTimerDelegate*pDelegate);private:static TIMER_MAPm_TimerMap;private:static void CALLBACKTimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);public://SetTimer设置定时器工作模式并启动定时器//参数:nElapse,定时器超时时间(毫秒)//lParam,附加的定时器参数,默认为空void SetTimer(UINT nElapse,LPVOID lParam = NULL);//杀死一个定时器BOOL KillTimer();public://通过委托创建一个 定时器(Timer) static CTimer*TimerWithDelegate(CTimerDelegate* pDelegate);};#endif // Timer_h__
//Timer.cpp#include "StdAfx.h"#include "Timer.h"////////////////////////////////////////////////////////////////////////////静态成员TIMER_MAPCTimer::m_TimerMap;////////////////////////////////////////////////////////////////////////////构造CTimer::CTimer(CTimerDelegate* pDelegate){m_pDelegate = pDelegate;}void CTimer::TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime){TIMER_MAP::iterator iter = m_TimerMap.find(nTimerid);if (iter != m_TimerMap.end()){CTimer* pTimer = iter->second;pTimer->m_pDelegate->OnTimer(pTimer,pTimer->m_lTimerParam);}}CTimer*CTimer::TimerWithDelegate(CTimerDelegate* pDelegate){CTimer *pTimer = new CTimer(pDelegate);return pTimer;}void CTimer::SetTimer(UINT nElapse,LPVOID lParam/* = NULL*/){UINT nTimerID = ::SetTimer(NULL,m_nTimerID,nElapse,TimerProc);m_lTimerParam = lParam;m_nTimerID = nTimerID;TIMER_MAP::iterator iter = m_TimerMap.find(m_nTimerID);if (iter == m_TimerMap.end()){//新的定时器,插入到map中 m_TimerMap.insert(TIMER_PAIR(nTimerID,this));}}BOOL CTimer::KillTimer(){BOOL bRet = FALSE;TIMER_MAP::iterator iter = m_TimerMap.find(m_nTimerID);if (iter != m_TimerMap.end()){CTimer* pTimer = iter->second;::KillTimer(NULL,m_nTimerID);m_TimerMap.erase(iter);bRet = TRUE;}delete this;return bRet;}
测试代码:
//main.cpp#include "stdafx.h"#include <cstdio>#include "Timer.h"class CTestTimerDelegate:public CTimerDelegate{private:const char *m_pName;public:CTestTimerDelegate(const char *pName){m_pName = pName;}public:virtual void OnTimer(CTimer *pTimer,LPVOID lParam){int &i = *(int *)lParam;i++;printf("OnTimer(%s):%d\n",m_pName,i);if (i >= 10){pTimer->KillTimer();}}};int main(int argc, char* argv[]){CTestTimerDelegate Obj1("Obj1"),Obj2("Obj2");CTimer *pTimer1 = CTimer::TimerWithDelegate(&Obj1);CTimer *pTimer2 = CTimer::TimerWithDelegate(&Obj2);int i = 0,j = 0;pTimer1->SetTimer(1000,&i);pTimer2->SetTimer(2000,&j); //由于是控制台程序,必须实现消息循环,不然timer不工作。MSG msg; while(GetMessage(&msg,NULL,0, 0)){ TranslateMessage(&msg); DispatchMessage(&msg); } return 0;}
- 基于委托机制的定时器的实现
- C++实现的委托机制
- C++实现的委托机制
- Nginx定时器机制的实现
- 学习委托(2)-------解析委托的实现机制
- 学习委托(2)-------解析委托的实现机制
- 学习委托(3)-----解析委托的实现机制续篇
- 学习委托(3)-----解析委托的实现机制续篇
- C++实现的委托机制(一)
- C++实现的委托机制(二)
- C++实现的委托机制(1)
- C++实现的委托机制(2)
- C++实现的委托机制(3)
- C++实现的委托机制(三)
- linux 中定时器的实现机制
- 基于Libevent最小根堆定时器的C++定时器实现
- 基于Libevent最小根堆定时器的C++定时器实现
- 基于ACE的定时器队列实现
- 模板特化
- 如何使用android.os.SystemProperties
- Android支持的长度单位。
- C#实现下载功能(好东东就应该保存学习)
- vi 替换命令
- 基于委托机制的定时器的实现
- ios菜鸟之路:用户注册 验证邮箱格式是否正确
- POJ 3264
- SWFUpload介绍 使用SWFUpload上传文件
- HDU 1711 Number Sequence
- 64位操作系统使用7.0版winiis系统,报ActiveX 部件不能创建对象问题!
- “安全删除硬件”图标 隐藏
- 如何判断是否为64位CPU
- 【Android】添加删除桌面快捷方式