定義:
#pragma once
#include <windows.h>
template <typename T>
class TTimerHandle
{
typedef void (T::*TimerHandle)();
T *m_pObj;
TimerHandle m_pfnHandle;
HWND m_hWnd;
public:
TTimerHandle(T *pObj, TimerHandle pfnHandle)
{
m_pObj = pObj;
m_pfnHandle = pfnHandle;
RegisterClass();
CreateWnd();
}
~TTimerHandle()
{
if (m_hWnd)
{
Stop();
CloseWindow(m_hWnd);
}
}
void Start(unsigned int uMinSeconds)
{
if (m_hWnd)
{
::SetTimer(m_hWnd, 1, uMinSeconds, NULL);
}
}
void Stop()
{
if (m_hWnd)
{
::KillTimer(m_hWnd, 1);
}
}
private:
BOOL RegisterClass()
{
WNDCLASS stWndClass;
stWndClass.style = CS_HREDRAW | CS_VREDRAW;
stWndClass.cbClsExtra = 0;
stWndClass.cbWndExtra = 0;
stWndClass.hInstance = ::GetModuleHandle(NULL);
stWndClass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
stWndClass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
stWndClass.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
stWndClass.lpszClassName = _T("MyThreadClass");
stWndClass.lpszMenuName = NULL;
stWndClass.lpfnWndProc = (WNDPROC)WndProc;
return ::RegisterClass(&stWndClass);
}
BOOL CreateWnd()
{
m_hWnd = ::CreateWindow(_T("MyThreadClass"), _T(""), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), this);
if (m_hWnd)
{
::ShowWindow(m_hWnd, SW_HIDE);
::UpdateWindow(m_hWnd);
}
return (m_hWnd != NULL);
}
static LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_NCCREATE:
{
CREATESTRUCT *pCreateStruct = (CREATESTRUCT*)lParam;
if (pCreateStruct)
{
::SetWindowLong(hWnd, GWL_USERDATA, (LONG)pCreateStruct->lpCreateParams);
}
}
break;
case WM_TIMER:
{
TTimerHandle<T> *pClass = (TTimerHandle<T>*)::GetWindowLong(hWnd, GWL_USERDATA);
if (pClass)
{
( (pClass->m_pObj)->*(pClass->m_pfnHandle) )();
}
}
break;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
};
使用:
class CTestTimer
{
public:
void TimerHandle()
{
::OutputDebugStringA("CTestTimer::Timer /n");
}
void TimerHandle2()
{
::OutputDebugStringA("CTestTimer::Timer2 /n");
}
TTimerHandle<CTestTimer> m_Timer1;
TTimerHandle<CTestTimer> m_Timer2;
CTestTimer() : m_Timer1(this, &CTestTimer::TimerHandle), m_Timer2(this, &CTestTimer::TimerHandle2)
{
m_Timer1.Start(5000);
m_Timer2.Start(10000);
}
};