用法和Windows API的timer类似 只不过要用类的实例
如:
SuperTimer st;
st.SetTimer(...........);
st.KillTimer(............);
/// high PRI timer
/// in this timer we'd better user less time than the timer interval
class SuperTimer
{
public:
SuperTimer()
{
InitializeCriticalSection(&m_cs);
InitializeCriticalSection(&m_cssend);
m_hEventForSendTimer = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hEventEndThread = CreateEvent(NULL, FALSE, FALSE, NULL);
uintptr_t tid = _beginthread(DoTimerThread, 0, this);
}
~SuperTimer()
{
SetEvent(m_hEventEndThread);
for(MMIDMAP::iterator pos = m_timerIDMap.begin(); pos != m_timerIDMap.end(); ++pos)
{
KillTimer(pos->first.first, pos->first.second);
}
CloseHandle(m_hEventEndThread);
CloseHandle(m_hEventForSendTimer);
DeleteCriticalSection(&m_cs);
DeleteCriticalSection(&m_cssend);
}
UINT_PTR SetTimer(__in_opt HWND hWnd, __in UINT_PTR nIDEvent, __in UINT uElapse, __in_opt TIMERPROC lpTimerFunc = NULL)
{
// CriticalLock clk(m_cskill);
CriticalLock cl(m_cs);
UserCallbackData *pucd = new UserCallbackData(hWnd, nIDEvent, this);
MMRESULT mmrt = timeSetEvent(uElapse, 200, (LPTIMECALLBACK)&TimeCallBack, (DWORD_PTR)pucd, TIME_PERIODIC);
if(!mmrt)
return 0;
m_timerIDMap[make_pair(hWnd, nIDEvent)] = make_pair(
mmrt,
pucd);
return nIDEvent;
}
void KillTimer(__in_opt HWND hWnd, __in UINT_PTR uIDEvent)
{
UserCallbackData *pucd = new UserCallbackData(hWnd, uIDEvent, this);
killTimerThread(pucd);
// uintptr_t tid = _beginthread(killTimerThread, 0, pucd);
}
private:
/// timer callback function
static void CALLBACK TimeCallBack(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
UserCallbackData *pucd = (UserCallbackData*)dwUser;
{
CriticalLock cl(pucd->psTimer->m_cssend);
pucd->psTimer->m_qcdataForSendTimer.push(*(UserCallbackData *)dwUser);
}
SetEvent(pucd->psTimer->m_hEventForSendTimer);
}
/// we kill timer in this function
static void killTimerThread(void *pdata)
{
UserCallbackData *pucd = (UserCallbackData*)pdata;
CriticalLock cl(pucd->psTimer->m_cs);
MMIDMAP::iterator pos = pucd->psTimer->m_timerIDMap.find(make_pair(pucd->hWnd, pucd->nIDEvent));
if(pos != pucd->psTimer->m_timerIDMap.end())
{
timeKillEvent(pos->second.first);
delete pos->second.second;
pucd->psTimer->m_timerIDMap.erase(pos);
}
delete pdata;
}
/// we send WM_TIMER messages in this thread
static void DoTimerThread(void *pdata)
{
SuperTimer *pThis = (SuperTimer*)pdata;
while(true)
{
HANDLE hEvents[] = {pThis->m_hEventForSendTimer, pThis->m_hEventEndThread };
DWORD dwrt = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
switch(dwrt)
{
case WAIT_OBJECT_0:
while(true)
{
UserCallbackData ucd;
{
CriticalLock cl(pThis->m_cssend);
if(pThis->m_qcdataForSendTimer.empty())
break;
ucd = pThis->m_qcdataForSendTimer.front();
pThis->m_qcdataForSendTimer.pop();
}
// CriticalLock cl(pucd->sTimer.m_cs);
SendMessage(ucd.hWnd, WM_TIMER, ucd.nIDEvent, 0);
}
break;
case WAIT_OBJECT_0 + 1:
_endthread();
break;
}
}
}
/// information for sending WM_TIMER message
struct UserCallbackData
{
UserCallbackData() : hWnd(NULL), nIDEvent(-1), psTimer(NULL)
{
}
UserCallbackData(HWND hwnd, UINT_PTR nevent, SuperTimer *pstimer) : hWnd(hwnd), nIDEvent(nevent), psTimer(pstimer)
{
}
UserCallbackData(const UserCallbackData &ucd) : hWnd(ucd.hWnd), nIDEvent(ucd.nIDEvent), psTimer(ucd.psTimer)
{
}
HWND hWnd;
UINT_PTR nIDEvent;
SuperTimer *psTimer;
};
/// timer map to maintain timers
typedef map
MMIDMAP m_timerIDMap;
CRITICAL_SECTION m_cs, m_cssend;
HANDLE m_hEventForSendTimer;
HANDLE m_hEventEndThread;
/// queue for WM_TIMER
queue
};