/******************************************************************** ***********
* LRTimer.h *
* *
* Written by Max Gurdziel the under GNU general public License *
* Contact Me:max[at]remotesos[dot]com *
* *
* Lrtimer is a-resolution timer class with own timing thread. IT allows *
* An external callback function to is supplied that would be called in *
* Pre-defined time intervals. *
* The smallest timer interval can be 1ms. *
* *
* Tested with GCC MinGW & Visual C + + 6.0 under Windows XP Home and Pro *
* *
* *
* Lrtimer timer; Define Lrtimer Object *
* Timer.setinterval (100); Set Interval of 100ms *
* TIMER.SETCALLBACKPROC (&mycallbackfunction, 0); Set Callback function *
*///It ' s prototype is: *
*//void Mycallbackfunction (void* pparam); *
* *
* Timer.start (); Start Timer *
* .... *
* Timer.stop (); Stops the timer *
* .... *
* Timer.start (200); Starts timer with new interval *
* *
* *
* Example Code: *
* Copy and paste below sample code to test Lrtimer *
* *
______________________________________________________________________________ __
#include <stdlib.h>
#include "LRTimer.h"
Define callback function
//
static void Mycallback (void* data)
{
static DWORD cnt = 0;
char c;
cnt++;
Switch (cnt% 4)
{
Case 0:c = ' | '; Break
Case 1:c = '/'; Break
Case 2:c = '-'; Break
Case 3:c = ' \ \ ';
}
printf ("\b%c", c);
}
int main (int argc, char *argv[])
{
Lrtimer LRT;
Lrt.setcallbackproc (&mycallback, NULL); Set the callback function by reference
Lrt.setinterval (50); Set delay interval in miliseconds
Lrt.start (); Start the timer
GetChar (); Let it run for a while-press Enter
Lrt.stop (); Stop the timer
GetChar (); Wait for show it ' s stopped-enter
Lrt.start (200); Start with different delay
GetChar ();
Lrt.stop ();
System ("PAUSE");
return 0;
}
______________________________________________________________________________ __
* *
* Permission to use, copy, modify, and distribute-software and its *
* Documentation under the terms of the GNU general public, License is hereby *
* Granted. No representations are made about the suitability of this software *
* For any purpose. It is provided ' as is ' without express or implied warranty. *
* http://www.gnu.org/copyleft/gpl.html for more details. *
* *
* All I ask is ' that ' if ' Lrtimer in your project retain the *
* Copyright notice. If you are have any comments and suggestions please email me *
* Max[at]remotesos[dot]com *
* *
****************************************************************************** */
#ifndef lrtimer_h__
#define Lrtimer_h__
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
Compile with:/mt/d "_x86_"/C
Processor:x86
#include <windows.h>
#include <process.h>/* _beginthread, _endthread * *
#include <stdio.h>
#include <assert.h>
Define a second in terms of the 100ns-used with waitable timer API
#define _SECOND 10000
typedef VOID (*LRTCALLBACKEVENTPROC) (void*);
Class Lrtimer
{
Public
Default constructor with 1 second interval
Lrtimer (DWORD dwinterval=1000);
Default destructor
~lrtimer ();
Starts timer by creating new thread. Interval must be set earlier
VOID start ();
Starts timer with given interval in miliseconds
VOID Start (DWORD _interval_ms);
Stops the timer
VOID Stop ();
Sets time interval in miliseconds
VOID setinterval (DWORD _interval_ms);
Returns time interval in MS
DWORD Getinterval ();
Sets function that would is called on time expiration
VOID Setcallbackproc (Lrtcallbackeventproc pcbeventproc, void* pcbparam);
Returns True if Lrtimer is currently running
BOOL isrunning ();
It should be used if the worker class would use CRT functions
Static HANDLE Crtcreatethread (Lpsecurity_attributes lpsa, DWORD dwstacksize, Lpthread_start_routine Pfnthreadproc, void *pvparam, DWORD dwcreationflags, DWORD *pdwthreadid) throw ()
{
Sanity Check for Pdwthreadid
ASSERT (sizeof (DWORD) = = sizeof (unsigned int));
_beginthreadex calls CreateThread which'll set the last error value before it returns
Return (HANDLE) _beginthreadex (LPSA, dwstacksize, (unsigned int (__stdcall *) (void *)) Pfnthreadproc, Pvparam, dwcreation Flags, (unsigned int *) pdwthreadid);
}
Private
DWORD M_dwinterval; Interval between alarms
Lrtcallbackeventproc M_pcallback; Pointer to user callback function
VOID *m_pcbparam; Pointer to user callback parameter
BOOL m_brunning; Timer Running state
HANDLE M_htimerthread; Handle to Timer thread
DWORD m_iid; Timer thread id-added for compatibility with WIN95/98
Timer clocking tread Runtine
Virtual DWORD WINAPI TimerThread ();
Wrapper to thread runtine so it can be used within a class
Static DWORD WINAPI Timerthreadadapter (pvoid _this)
{
Return ((lrtimer*) _this)->timerthread ();
}
Timer callback APC procedure called when timer is signaled
Virtual VOID CALLBACK Timerapcproc (LPVOID, DWORD, DWORD);
Wrapper to callback APC procedure, it can be used within a class
Static VOID CALLBACK timerapcprocadapter (Pvoid _this, DWORD a1=0, DWORD a2=0)
{
((lrtimer*) _this)->timerapcproc (NULL, a1, A2);
}
};
#endif
/***************************************************************************** **
* LRTimer.cpp *
* *
* Written by Max Gurdziel the under GNU general public License *
* Contact Me:max[at]remotesos[dot]com *
* *
* Lrtimer is a-resolution timer class with own timing thread. IT allows *
* An external callback function to is supplied that would be called in *
* Pre-defined time intervals. The smallest timer interval can be 1ms. *
* *
* The header file for more info, usage information and example *
* *
* *
* *
* Permission to use, copy, modify, and distribute-software and its *
* Documentation under the terms of the GNU general public, License is hereby *
* Granted. No representations are made about the suitability of this software *
* For any purpose. It is provided ' as is ' without express or implied warranty. *
* http://www.gnu.org/copyleft/gpl.html for more details. *
* *
* All I ' ask is ' that ' if you ' Lrtimer in your project you retain the *
* Copyright notice. If you are have any comments and suggestions please email me *
* Max[at]remotesos[dot]com *
* *
* 2008-6-23 Modified by Zhangliang *
* *
****************************************************************************** */
#include "stdafx.h"
#include "LRTimer.h"
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
Lrtimer::lrtimer (DWORD dwinterval):
M_dwinterval (Dwinterval),
M_brunning (FALSE),
M_pcallback (NULL),
M_pcbparam (NULL),
M_htimerthread (0)
{}
Lrtimer::~lrtimer ()
{}
VOID CALLBACK Lrtimer::timerapcproc (LPVOID, DWORD, DWORD)
{
Call Custom callback function
if (NULL!= m_pcallback)
(*m_pcallback) (M_pcbparam);
#ifdef _DEBUG
Else
printf ("No callback function set\n");
#endif
}
DWORD WINAPI Lrtimer::timerthread ()
{
HANDLE Htimer;
BOOL bsuccess;
Large_integer Liduetime;
CHAR szerror[255];
CHAR sztimername[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,//Handle to the Timer object
&liduetime,//when timer would become signaled
M_dwinterval,//Periodic timer interval
Timerapcprocadapter,//completion routine
This is,//Argument to the completion routine
FALSE); Do not restore a suspended system
if (bsuccess) {
while (m_brunning)
SleepEx (1, TRUE); SleepEx (0, TRUE) consumes 100% CPU usage
Cancelwaitabletimer (Htimer);
} else {
WSPRINTFA (Szerror, "SetWaitableTimer failed with Error% d.", GetLastError ());
#ifdef _DEBUG
MessageBoxA (NULL, Szerror, "Error", mb_iconexclamation);
#endif
return 1;
}
CloseHandle (Htimer);
return 0;
}
VOID Lrtimer::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 ("CreateThread failed (%d) \ n", GetLastError ());
#endif
Return
}
}
VOID Lrtimer::start (DWORD _interval_ms)
{
SetInterval (_interval_ms);
Start ();
}
VOID Lrtimer::stop ()
{
m_brunning = FALSE;
CloseHandle (M_htimerthread);
M_htimerthread = 0;
}
VOID lrtimer::setinterval (DWORD _interval_ms)
{
M_dwinterval = _interval_ms;
}
DWORD Lrtimer::getinterval ()
{
return m_dwinterval;
}
VOID Lrtimer::setcallbackproc (Lrtcallbackeventproc pcbeventproc, void* Pcbparam)
{
M_pcallback = Pcbeventproc;
M_pcbparam = Pcbparam;
}
BOOL lrtimer::isrunning ()
{
return m_brunning;
}