📄 sh_timer.cpp
字号:
// SH_Timer.cpp: implementation of the SH_Timer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SH_Timer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include "SH_Tree.h"
typedef VOID (WINAPI *WAITORTIMERCALLBACK)(PVOID,BOOL);
typedef HANDLE (WINAPI * LPFNCREATETIMERQUEUE)();
typedef BOOL (WINAPI * LPFNCREATETIMERQUEUETIMER)(
PHANDLE,
HANDLE,
WAITORTIMERCALLBACK,
PVOID,
DWORD,
DWORD,
ULONG);
typedef BOOL (WINAPI * LPFNDELETETIMERQUEUETIMER)(
HANDLE,
HANDLE,
HANDLE);
static SH_Tree<DWORD,SH_Timer*> SH_NormalTimerTree;
static VOID CALLBACK SH_TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime);
static VOID WINAPI SH_TimerQueueCallback(PVOID pvContext,BOOL bWaitOrExpired);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SH_Timer::SH_Timer()
{
m_dwTimerId = 0;
m_hTimer = NULL;
m_nElapse = 0;
m_nKernelElapse = 0;
SetCallback(NULL);
}
SH_Timer::SH_Timer(SH_TimerCallback lpfnCallback)
{
m_dwTimerId = 0;
m_hTimer = NULL;
m_nElapse = 0;
m_nKernelElapse = 0;
SetCallback(lpfnCallback);
}
SH_Timer::~SH_Timer()
{
KillTimer();
KillKernelTimer();
}
DWORD SH_Timer::GetTimerId() const
{
return m_dwTimerId;
}
BOOL SH_Timer::SetTimer(UINT elapse,LPVOID pUserData)
{
BOOL bRet;
KillTimer();
m_dwTimerId = ::SetTimer(NULL,0x01,elapse,(TIMERPROC)SH_TimerProc);
SetUserData(pUserData);
SetElapse(elapse);
bRet = m_dwTimerId > 0 ? TRUE:FALSE;
if(bRet)
{
bRet = SH_NormalTimerTree.Insert(m_dwTimerId,this);
}
return bRet;
}
BOOL SH_Timer::KillTimer()
{
if(m_dwTimerId > 0)
{
SH_Timer * Timer;
::KillTimer(NULL,m_dwTimerId);
SH_NormalTimerTree.Remove(m_dwTimerId,Timer);
m_dwTimerId = 0;
}
return TRUE;
}
VOID SH_Timer::SetCallback(SH_TimerCallback lpfnCallback)
{
m_lpfnCallback = lpfnCallback;
}
SH_TimerCallback SH_Timer::GetCallback()
{
return m_lpfnCallback;
}
BOOL SH_Timer::Wait(int ms)
{
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
char cszName[64] = {0};
liDueTime.QuadPart=-10000*ms;
sprintf(cszName,"SH_Timer#%d",this);
// Create a waitable timer.
hTimer = CreateWaitableTimer(NULL, TRUE, cszName);
if (hTimer)
{
if (SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
{
if (WaitForSingleObject(hTimer, INFINITE) == WAIT_OBJECT_0)
{
CloseHandle(hTimer);
return TRUE;
}
}
CloseHandle(hTimer);
}
//Wait timer does not work,use SleepEx instead.
SleepEx(ms,FALSE);
return TRUE;
}
int SH_Timer::GetElpase() const
{
return m_nElapse;
}
int SH_Timer::GetKernelElpase() const
{
return m_nKernelElapse;
}
HANDLE SH_Timer::GetTimerHandle() const
{
return m_hTimer;
}
VOID SH_Timer::SetElapse(const int ms)
{
m_nElapse = ms;
}
VOID SH_Timer::SetKernelElapse(const int ms)
{
m_nKernelElapse = ms;
}
BOOL SH_Timer::SetKernelTimer(UINT elapse,LPVOID pUserData)
{
HMODULE hLib;
LPFNCREATETIMERQUEUETIMER lpfnCreateTimerQueueTimer;
KillKernelTimer();
hLib = ::LoadLibrary("kernel32.dll");
if(hLib == NULL || hLib == INVALID_HANDLE_VALUE)
return FALSE;
lpfnCreateTimerQueueTimer = (LPFNCREATETIMERQUEUETIMER)GetProcAddress(hLib,"CreateTimerQueueTimer");
if(lpfnCreateTimerQueueTimer == NULL)
{
::FreeLibrary(hLib);
return FALSE;
}
if(lpfnCreateTimerQueueTimer(&m_hTimer,
NULL,
(WAITORTIMERCALLBACK)SH_TimerQueueCallback,
(PVOID)this,
0,
elapse,
0))
{
SetUserData(pUserData);
SetKernelElapse(elapse);
::FreeLibrary(hLib);
return TRUE;
}
::FreeLibrary(hLib);
return FALSE;
}
BOOL SH_Timer::KillKernelTimer()
{
if(m_hTimer)
{
HMODULE hLib;
LPFNDELETETIMERQUEUETIMER lpfnDeleteTimerQueueTimer;
hLib = ::LoadLibrary("kernel32.dll");
if(hLib == NULL || hLib == INVALID_HANDLE_VALUE)
return FALSE;
lpfnDeleteTimerQueueTimer = (LPFNDELETETIMERQUEUETIMER)GetProcAddress(hLib,"DeleteTimerQueueTimer");
if(lpfnDeleteTimerQueueTimer == NULL)
{
::FreeLibrary(hLib);
return FALSE;
}
lpfnDeleteTimerQueueTimer(NULL,m_hTimer,NULL);
m_hTimer = NULL;
::FreeLibrary(hLib);
}
return TRUE;
}
static VOID CALLBACK SH_TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
{
SH_Timer * Timer;
if(SH_NormalTimerTree.Search(idEvent,Timer))
{
if(Timer)
{
if(Timer->GetCallback())
Timer->GetCallback()(idEvent,Timer->GetUserData());
else
Timer->OnTimer(Timer->GetUserData());
}
}
}
static VOID WINAPI SH_TimerQueueCallback(PVOID pvContext,BOOL bWaitOrExpired)
{
SH_Timer * Timer = (SH_Timer*)pvContext;
if(Timer)
{
if(Timer->GetCallback())
Timer->GetCallback()((DWORD)Timer->GetTimerHandle(),Timer->GetUserData());
else
Timer->OnTimer(Timer->GetUserData());
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -