1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
class Timer
{
private:
static unsigned int TimerCount;
HANDLE m_timerHandle=0;
UINT_PTR timerid;
UINT m_uResolution=0;
UINT resolution=0;
unsigned int TimerID=0;
DWORD intInterval=0;
WNDCLASSEX wc;
static HWND hwnd;
bool blnTimerDestroyed=false;
const char *g_szClassName = "myWindowClass";
static LRESULT CALLBACK TimerWindow(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_TIMER:
{
Timer* obj=reinterpret_cast<Timer*>(wParam);
if(obj->timerprocedure!=nullptr)
{
obj->timerprocedure();
}
else
DebugText("no timer");
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
static void CALLBACK MultimediaTimerFunction(UINT wTimerID, UINT msg, DWORD InstancePointer, DWORD dw1, DWORD dw2)
{
Timer* obj=(Timer*)(InstancePointer);
if(obj->timerprocedure!=nullptr)
obj->timerprocedure();
else
DebugText("error no timer");
}
public:
std::function<void()> timerprocedure=EmptyEvent;
Timer(std::function<void()> tmrprocedure=EmptyEvent)
{
TimerCount+=1;
TimerID=TimerCount-1;
timerprocedure=tmrprocedure;
}
void Stop()
{
if(timerid!=0 || timerid!=NULL)
{
if(intInterval<10)
{
// destroy the timer
timeKillEvent(timerid);
// reset the timer
timeEndPeriod (m_uResolution);
}
else
{
if(KillTimer(hwnd,timerid)==FALSE)
DebugText("error on destroying the timer: " + to_string(GetLastError()) + "\ttimer id" + to_string(TimerID));
}
}
}
DWORD GetInterval()
{
return intInterval;
}
void SetInterval(DWORD uintInterval)
{
intInterval = uintInterval;
}
property <DWORD> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};
void Start()
{
if(timerid!=0)
Stop();
if(intInterval<10)
{
TIMECAPS tc;
timeGetDevCaps(&tc, sizeof(TIMECAPS));
m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
timeBeginPeriod(m_uResolution);
timerid=timeSetEvent(intInterval, m_uResolution,&Timer::MultimediaTimerFunction ,(DWORD)this, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
}
else
{
if(hwnd==NULL)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = Timer::TimerWindow;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"My Timer Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, GetModuleHandle(NULL), NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
}
ShowWindow(hwnd, SW_HIDE);
UpdateWindow(hwnd);
}
if(hwnd==NULL)
DebugText("no window");
timerid=SetTimer(hwnd, reinterpret_cast<UINT_PTR>(this), intInterval,NULL);
}
if(timerid==0 || timerid==NULL)
DebugText("error: " + to_string(GetLastError()));
}
~Timer()
{
if(timerid!=0)
Stop();
TimerCount-=1;
if(TimerCount==0 && hwnd!=NULL)
DestroyWindow(hwnd);
}
};
unsigned int Timer::TimerCount=0;
HWND Timer::hwnd=NULL;
|