windowsタイマー

3089 ワード

現在、個人が把握しているwindowsタイマーには三つの方式があります.
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;
};