.h文件如下:
#pragma once
#include <windows.h>
typedef VOID (CALLBACK* TIMERNOTIFYPROC)(UINT TimerID,struct TimerInfoTag* TimerInfo);
typedef struct TimerInfoTag
{
UINT uElapse;
TIMERNOTIFYPROC lpTimerFunc;
LPVOID argc;
BOOL once;
//返回值
UINT Result;
UINT TiemrID;
}TIMERINFO,*LPTIMERINFO;
#ifdef TIMERMODULE_EXPORTS
class __declspec(dllexport) CLiteTimer
#else
class __declspec(dllimport) CLiteTimer
#endif
{
public:
CLiteTimer();
static CLiteTimer& StaticInstance();
void StartTimer();
void StopTimer();
BOOL SetTimer(LPTIMERINFO TimerInfo);
BOOL KillTimer(LPTIMERINFO TimerInfo);
static LPTIMERINFO Alloc(UINT uElapse,TIMERNOTIFYPROC lpTimerFunc, LPVOID argc,BOOL once,int enlarge=0);
static void Free(LPTIMERINFO TimerInfo);
private:
static DWORD WINAPI WorkThreadProc(LPVOID);
DWORD m_threadid;
};
.cpp文件
#include "StdAfx.h"
#include "LiteTimer.h"
#define WM_SETTIMER WM_USER+100
#define WM_KILLTIMER WM_USER+101
#define WM_STOPTIMER WM_USER+102
CLiteTimer::CLiteTimer():
m_threadid(0)
{
}
CLiteTimer& CLiteTimer::StaticInstance()
{
static CLiteTimer LiteTimer;
return LiteTimer;
}
void CLiteTimer::StartTimer()
{
if(m_threadid==NULL)
{
HANDLE hEvent=::CreateEvent(NULL,FALSE,FALSE,NULL);
::CreateThread(NULL,0,CLiteTimer::WorkThreadProc,hEvent,0,&m_threadid);
WaitForSingleObject(hEvent,INFINITE);
::CloseHandle(hEvent);
}
}
void CLiteTimer::StopTimer()
{
if(m_threadid!=NULL)
{
HANDLE hEvent=::CreateEvent(NULL,FALSE,FALSE,NULL);
::PostThreadMessage(m_threadid,WM_STOPTIMER,(WPARAM)hEvent,0);
m_threadid=0;
WaitForSingleObject(hEvent,INFINITE);
::CloseHandle(hEvent);
}
}
BOOL CLiteTimer::SetTimer(LPTIMERINFO TimerInfo)
{
if(m_threadid!=NULL)
{
if(TimerInfo->Result==-1) return FALSE;
return ::PostThreadMessage(m_threadid,WM_SETTIMER,0,(LPARAM)TimerInfo);
}
return FALSE;
}
BOOL CLiteTimer::KillTimer(LPTIMERINFO TimerInfo)
{
if(m_threadid!=NULL)
{
TimerInfo->Result=-1;
if(TimerInfo->once)
{
return TRUE;
}
return ::PostThreadMessage(m_threadid,WM_KILLTIMER,0,(LPARAM)TimerInfo);
}
return FALSE;
}
LPTIMERINFO CLiteTimer::Alloc(UINT uElapse,TIMERNOTIFYPROC lpTimerFunc, LPVOID argc,BOOL once,int enlarge)
{
LPTIMERINFO lpTimerInfo = (LPTIMERINFO)new char[sizeof(TIMERINFO)+enlarge];
lpTimerInfo->uElapse=uElapse;
lpTimerInfo->lpTimerFunc=lpTimerFunc;
lpTimerInfo->argc=argc;
lpTimerInfo->once=once;
lpTimerInfo->TiemrID=0;
lpTimerInfo->Result=0;
return lpTimerInfo;
}
void CLiteTimer::Free(LPTIMERINFO TimerInfo)
{
delete TimerInfo;
}
DWORD WINAPI CLiteTimer::WorkThreadProc(LPVOID Param)
{
MSG msg;
PeekMessage(&msg,0,0,0,PM_NOREMOVE);
::SetEvent((HANDLE)Param);
while(GetMessage(&msg,0,0,0))
{
switch(msg.message)
{
case WM_TIMER:
{
if(((LPTIMERINFO)msg.lParam)->Result!=-1)
{
((LPTIMERINFO)msg.lParam)->lpTimerFunc((UINT)msg.wParam,(LPTIMERINFO)msg.lParam);
}
if(((LPTIMERINFO)msg.lParam)->once)
{
CLiteTimer::Free((LPTIMERINFO)msg.lParam);
::KillTimer(0,(UINT)msg.wParam);
}
}
break;
case WM_SETTIMER:
{
if(((LPTIMERINFO)msg.lParam)->TiemrID!=-1)
{
((LPTIMERINFO)msg.lParam)->TiemrID=::SetTimer(0,((LPTIMERINFO)msg.lParam)->TiemrID,((LPTIMERINFO)msg.lParam)->uElapse,(TIMERPROC)msg.lParam);
((LPTIMERINFO)msg.lParam)->Result=1;
}
}
break;
case WM_KILLTIMER:
{
::KillTimer(0,(UINT)((LPTIMERINFO)msg.lParam)->TiemrID);
CLiteTimer::Free((LPTIMERINFO)msg.lParam);
}
break;
case WM_STOPTIMER:
{
::SetEvent((HANDLE)msg.wParam);
::ExitThread(1);
}
break;
}
}
return 1;
}