- /*******************************************************************************
- *LRTimer.h*
- **
- *WrittenbyMaxGurdziel2005underGNUGeneralPublicLicense*
- *contactme:max[at]remoteSOS[dot]com*
- **
- *LRTimerisalowresolutiontimerclasswithowntimingthread.Itallows*
- *anexternalcallbackfunctiontobesuppliedthatwillbecalledin*
- *pre-definedtimeintervals.*
- *Thesmallesttimerintervalyoucanuseis1ms.*
- **
- *Testedwithgccmingw&VisualC++6.0underWindowsXPHomeandPro*
- **
- **
- *LRTimertimer;//defineLRTimerobject*
- *timer.setInterval(100);//setintervalof100ms*
- *timer.setCallbackProc(&myCallbackFunction,0);//setcallbackfunction*
- *//it'sprototypeis:*
- *//voidmyCallbackFunction(void*pParam);*
- **
- *timer.start();//startthetimer*
- *....*
- *timer.stop();//stopsthetimer*
- *....*
- *timer.start(200);//startstimerwithnewinterval*
- **
- **
- *Examplecode:*
- *CopyandpastebelowsamplecodetotestLRTimer*
- **
- ________________________________________________________________________________
- #include<stdlib.h>
- #include"LRTimer.h"
- //definecallbackfunction
- //
- staticvoidmyCallback(void*data)
- {
- staticDWORDcnt=0;
- charc;
- cnt++;
- switch(cnt%4)
- {
- case0:c='|';break;
- case1:c='/';break;
- case2:c='-';break;
- case3:c='//';
- }
- printf("/b%c",c);
- }
- intmain(intargc,char*argv[])
- {
- LRTimerlrt;
- lrt.setCallbackProc(&myCallback,NULL);//setthecallbackfunctionbyreference
- lrt.setInterval(50);//setdelayintervalinmiliseconds
- lrt.start();//startthetimer
- getchar();//letitrunforawhile-pressEnter
- lrt.stop();//stopthetimer
- getchar();//waittoshowit'sstopped-Enter
- lrt.start(200);//startwithdifferentdelay
- getchar();
- lrt.stop();
- system("PAUSE");
- return0;
- }
- ________________________________________________________________________________
- **
- *Permissiontouse,copy,modify,anddistributethissoftwareandits*
- *documentationunderthetermsoftheGNUGeneralPublicLicenseishereby*
- *granted.Norepresentationsaremadeaboutthesuitabilityofthissoftware*
- *foranypurpose.Itisprovided"asis"withoutexpressorimpliedwarranty.*
- *Seehttp://www.gnu.org/copyleft/gpl.htmlformoredetails.*
- **
- *AllIaskisthatifyouuseLRTimerinyourprojectretainthe*
- *copyrightnotice.Ifyouhaveanycommentsandsuggestionspleaseemailme*
- *max[at]remoteSOS[dot]com*
- **
- *******************************************************************************/
- #ifndefLRTIMER_H__
- #defineLRTIMER_H__
- #ifndef_WIN32_WINNT
- #define_WIN32_WINNT0x0500
- #endif
- //compilewith:/MT/D"_X86_"/c
- //processor:x86
- #include<windows.h>
- #include<process.h>/*_beginthread,_endthread*/
- #include<stdio.h>
- #include<assert.h>
- //defineasecondintermsof100ns-usedwithwaitabletimerAPI
- #define_SECOND10000
- typedefVOID(*LRTCallbackEventProc)(VOID*);
- classLRTimer
- {
- public:
- //defaultconstructorwith1secondinterval
- LRTimer(DWORDdwInterval=1000);
- //defaultdestructor
- ~LRTimer();
- //startstimerbycreatingnewthread.intervalmustbesetearlier
- VOIDstart();
- //startstimerwithgivenintervalinmiliseconds
- VOIDstart(DWORD_interval_ms);
- //stopsthetimer
- VOIDstop();
- //setstimeintervalinmiliseconds
- VOIDsetInterval(DWORD_interval_ms);
- //returnstimeintervalinms
- DWORDgetInterval();
- //setsfunctionthatwillbecalledontimeexpiration
- VOIDsetCallbackProc(LRTCallbackEventProcpcbEventProc,VOID*pcbParam);
- //returnstrueifLRtimeriscurrentlyrunning
- BOOLisRunning();
- //ItshouldbeusediftheworkerclasswilluseCRTfunctions
- staticHANDLECrtCreateThread(LPSECURITY_ATTRIBUTESlpsa,DWORDdwStackSize,LPTHREAD_START_ROUTINEpfnThreadProc,void*pvParam,DWORDdwCreationFlags,DWORD*pdwThreadId)throw()
- {
- //sanitycheckforpdwThreadId
- assert(sizeof(DWORD)==sizeof(unsignedint));
- //_beginthreadexcallsCreateThreadwhichwillsetthelasterrorvaluebeforeitreturns
- return(HANDLE)_beginthreadex(lpsa,dwStackSize,(unsignedint(__stdcall*)(void*))pfnThreadProc,pvParam,dwCreationFlags,(unsignedint*)pdwThreadId);
- }
- private:
- DWORDm_dwInterval;//intervalbetweenalarms
- LRTCallbackEventProcm_pCallback;//pointertousercallbackfunction
- VOID*m_pcbParam;//pointertousercallbackparameter
- BOOLm_bRunning;//timerrunningstate
- HANDLEm_hTimerThread;//handletotimerthread
- DWORDm_iID;//timerthreadid-addedforcompatibilitywithWin95/98
- //timerclockingtreadruntine
- virtualDWORDWINAPItimerThread();
- //wrappertothreadruntinesoitcanbeusedwithinaclass
- staticDWORDWINAPItimerThreadAdapter(PVOID_this)
- {
- return((LRTimer*)_this)->timerThread();
- }
- //timercallbackAPCprocedurecalledwhentimerissignaled
- virtualVOIDCALLBACKTimerAPCProc(LPVOID,DWORD,DWORD);
- //wrappertocallbackAPCproceduresoitcanbeusedwithinaclass
- staticVOIDCALLBACKTimerAPCProcAdapter(PVOID_this,DWORDa1=0,DWORDa2=0)
- {
- ((LRTimer*)_this)->TimerAPCProc(NULL,a1,a2);
- }
- };
- #endif
- /*******************************************************************************
- *LRTimer.cpp*
- **
- *WrittenbyMaxGurdziel2005underGNUGeneralPublicLicense*
- *contactme:max[at]remoteSOS[dot]com*
- **
- *LRTimerisalowresolutiontimerclasswithowntimingthread.Itallows*
- *anexternalcallbackfunctiontobesuppliedthatwillbecalledin*
- *pre-definedtimeintervals.Thesmallesttimerintervalyoucanuseis1ms.*
- **
- *Seeheaderfileformoreinfo,usageinformationandexample*
- **
- **
- **
- *Permissiontouse,copy,modify,anddistributethissoftwareandits*
- *documentationunderthetermsoftheGNUGeneralPublicLicenseishereby*
- *granted.Norepresentationsaremadeaboutthesuitabilityofthissoftware*
- *foranypurpose.Itisprovided"asis"withoutexpressorimpliedwarranty.*
- *Seehttp://www.gnu.org/copyleft/gpl.htmlformoredetails.*
- **
- *AllIaskisthatifyouuseLRTimerinyourprojectyouretainthe*
- *copyrightnotice.Ifyouhaveanycommentsandsuggestionspleaseemailme*
- *max[at]remoteSOS[dot]com*
- **
- *2008-6-23ModifiedbyZhangLiang*
- **
- *******************************************************************************/
- #include"stdafx.h"
- #include"LRTimer.h"
- #ifndef_WIN32_WINNT
- #define_WIN32_WINNT0x0500
- #endif
- LRTimer::LRTimer(DWORDdwInterval):
- m_dwInterval(dwInterval),
- m_bRunning(FALSE),
- m_pCallback(NULL),
- m_pcbParam(NULL),
- m_hTimerThread(0)
- {}
- LRTimer::~LRTimer()
- {}
- VOIDCALLBACKLRTimer::TimerAPCProc(LPVOID,DWORD,DWORD)
- {
- //callcustomcallbackfunction
- if(NULL!=m_pCallback)
- (*m_pCallback)(m_pcbParam);
- #ifdef_DEBUG
- else
- printf("Nocallbackfunctionset/n");
- #endif
- }
- DWORDWINAPILRTimer::timerThread()
- {
- HANDLEhTimer;
- BOOLbSuccess;
- LARGE_INTEGERliDueTime;
- CHARszError[255];
- CHARszTimerName[16];
- sprintf_s(szTimerName,"LRT_%x",(DWORD)(DWORD_PTR)this);
- if(hTimer=CreateWaitableTimerA(NULL,FALSE,szTimerName))
- liDueTime.QuadPart=-(LONGLONG)m_dwInterval*_SECOND;
- bSuccess=SetWaitableTimer(
- hTimer,//Handletothetimerobject
- &liDueTime,//Whentimerwillbecomesignaledfirsttime
- m_dwInterval,//Periodictimerinterval
- TimerAPCProcAdapter,//Completionroutine
- this,//Argumenttothecompletionroutine
- FALSE);//Donotrestoreasuspendedsystem
- if(bSuccess){
- while(m_bRunning)
- SleepEx(1,TRUE);//SleepEx(0,TRUE)consumes100%CPUusage
- CancelWaitableTimer(hTimer);
- }else{
- wsprintfA(szError,"SetWaitableTimerfailedwithError%d.",GetLastError());
- #ifdef_DEBUG
- MessageBoxA(NULL,szError,"Error",MB_ICONEXCLAMATION);
- #endif
- return1;
- }
- CloseHandle(hTimer);
- return0;
- }
- VOIDLRTimer::start()
- {
- m_bRunning=TRUE;
- if(m_hTimerThread!=0)
- stop();
- #ifndef_INC_CRTDEFS
- m_hTimerThread=CreateThread(NULL,0,timerThreadAdapter,this,0,&m_iID);
- #else
- m_hTimerThread=CrtCreateThread(NULL,0,timerThreadAdapter,this,0,&m_iID);
- #endif
- if(m_hTimerThread==NULL)
- {
- #ifdef_DEBUG
- printf("CreateThreadfailed(%d)/n",GetLastError());
- #endif
- return;
- }
- }
- VOIDLRTimer::start(DWORD_interval_ms)
- {
- setInterval(_interval_ms);
- start();
- }
- VOIDLRTimer::stop()
- {
- m_bRunning=FALSE;
- CloseHandle(m_hTimerThread);
- m_hTimerThread=0;
- }
- VOIDLRTimer::setInterval(DWORD_interval_ms)
- {
- m_dwInterval=_interval_ms;
- }
- DWORDLRTimer::getInterval()
- {
- returnm_dwInterval;
- }
- VOIDLRTimer::setCallbackProc(LRTCallbackEventProcpcbEventProc,VOID*pcbParam)
- {
- m_pCallback=pcbEventProc;
- m_pcbParam=pcbParam;
- }
- BOOLLRTimer::isRunning()
- {
- returnm_bRunning;
- }