目前,我的掌握的windows定时器有三种方式(使用vs08测试,都可在控制台下实现):windows
1.使用线程方式与waitforsingleobject结合;函数
2.使用SetTimer;测试
3.使用多媒体定时器;this
代码以下:spa
SetTimer定时器封装以下:线程
#pragma once #include "vos/vos.h" #define _WIN32_WINNT 0x0400 #include <atltime.h> #include <windows.h> class CWin32Timer { public: CWin32Timer(TIMERPROC fun, unsigned int interval = 1000) : m_OnTimerFun(fun), m_interval(interval), m_isRunning(false) { CreateStopEvent(); DWORD dwThreadId; HANDLE hThread = CreateThread(NULL, 0, ThreadFun, (void*)this, 0, &dwThreadId); } virtual ~CWin32Timer() { Stop(); ReleaseStopEvent(); } private: static DWORD CALLBACK ThreadFun(void* para) { CWin32Timer* obj = (CWin32Timer*)para; if(0 == obj) return 1; obj->SetIsRunning(true); BOOL bRet; MSG msg; PeekMessage(&msg,NULL,WM_USER,WM_USER,PM_NOREMOVE); UINT timerid = ::SetTimer(NULL, 111, obj->m_interval, obj->m_OnTimerFun); while ((bRet = GetMessage(&msg,NULL,0,0))!=0) { if (bRet==-1) { // handle the error and possibly exit } else { TranslateMessage(&msg); DispatchMessage(&msg); } //检查到退出信号就退出线程 if(VOS_ERR_QUE_TIMEOUT != VOS_WaitEvent(&obj->m_StopThreadEvent, 0)) break; } KillTimer(NULL,timerid); obj->SetIsRunning(false); return 0; } void Stop() { if(!IsRunning()) return; VOS_SetEvent(&m_StopThreadEvent); while (IsRunning()) { VOS_Sleep(1); } } void SetIsRunning(bool state) { m_isRunning = state; } bool IsRunning() { return m_isRunning; } void CreateStopEvent() { VOS_CreateEvent(&m_StopThreadEvent); } void ReleaseStopEvent() { VOS_DestroyEvent(&m_StopThreadEvent); } private: TIMERPROC m_OnTimerFun; unsigned int m_interval; bool m_isRunning; VOS_Event m_StopThreadEvent; };
使用多媒体定时器封装以下:code
#pragma once #include <windows.h> #include <mmsystem.h> #pragma comment(lib,"winmm") class CWinMultimediaTimer { public: CWinMultimediaTimer(LPTIMECALLBACK callBack, DWORD_PTR dwUser = 0, unsigned int interval = 1000) : m_timerID(0) { CreateTimer(callBack, dwUser, interval); } ~CWinMultimediaTimer() { DestroyTimer(); } private: bool CreateTimer(LPTIMECALLBACK callBack, DWORD_PTR dwUser, unsigned int interval) { TIMECAPS tc; UINT wTimerRes; //设置多媒体定时器 if(timeGetDevCaps(&tc,sizeof(TIMECAPS)) != TIMERR_NOERROR)//向机器申请一个多媒体定时器 return false; //得到机器容许的时间间隔(通常可达到1毫秒) wTimerRes = min( max(tc.wPeriodMin, 1), tc.wPeriodMax); //调用回调函数timerback(),wTimerID为定时器ID.TIME_PERIODIC表周期性调用,TIME_ONESHOT表只产生一次事件 m_timerID = timeSetEvent(interval, wTimerRes, callBack, dwUser, TIME_PERIODIC); if(m_timerID == 0) return false; return true; } //删除定时器 void DestroyTimer() { if (!m_timerID) return; timeKillEvent(m_timerID); m_timerID = 0; } private: MMRESULT m_timerID; };