windows定时器

目前,个人掌握的windows定时器有三种方式(使用vs08测试,均可在控制台下实现):

1.使用线程方式与waitforsingleobject结合;

2.使用SetTimer;

3.使用多媒体定时器;

代码如下:

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;
};

使用多媒体定时器封装如下:

#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;
};

你可能感兴趣的:(windows定时器)