Below is complete repro code. Thanks BilalD for reporting this.
<code>
// timerbug.cpp
//
// This code reproduces a bug in timeSetEvent() where if a periodic timing
event is set for
// a interval larger than 429496 milliseconds, a wrap occurs and the timing
interval is
// actually x-429496 milliseconds. This also occurs at the mulitple,
858992 where the
// result will be x-858992 milliseconds.
// This bug only effects PERIODIC timers, it does not seem to effect
ONESHOT timers.
#pragma comment ( lib, "winmm.lib" )
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <mmsystem.h>
HANDLE g_timerEvent;
DWORD g_Start;
#define TIMER_INTERVAL 430000
#define MILLIPERSEC 1000.0
void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD
dw2);
int _tmain(int argc, _TCHAR* argv[])
{
printf("Press any key to start timer for %0.3f seconds\n",
TIMER_INTERVAL/MILLIPERSEC);
getch();
TIMECAPS caps;
timeGetDevCaps(&caps, sizeof(TIMECAPS));
printf("Timer caps min:%i max:%i\n", caps.wPeriodMin, caps.wPeriodMax);
g_timerEvent = CreateEvent(NULL, 0, FALSE, NULL);
g_Start = GetTickCount();
MMRESULT result = timeSetEvent(TIMER_INTERVAL, 1000, TimerProc, 0,
TIME_PERIODIC);
// wait for the timerproc to receive timing event
WaitForSingleObject(g_timerEvent, INFINITE);
printf("Test complete\n");
DWORD duration = GetTickCount()-g_Start;
printf("Our timer lasted for %0.3f seconds\n", duration/MILLIPERSEC);
int diff = (int)duration - TIMER_INTERVAL;
diff = abs(diff);
if (diff > 1000)
printf("The timer is broken. Expected %0.1fs, got %0.1fs\n",
TIMER_INTERVAL/MILLIPERSEC, duration/MILLIPERSEC);
else
printf("The timer is working OK.\n");
CloseHandle(g_timerEvent);
getch();
return 0;
}
void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD
dw2)
{
timeKillEvent(uID);
SetEvent(g_timerEvent);
}
</code>
"Chris P." <ms...@chrisnet.net> wrote in message
news:q9ca7uqmj1rd$.1v08n1w09vq3u.dlg@40tude.net...
> Looks like the internal math to convert miliseconds to 100 ns units is using
> 32 bits. This means anything more that2^32 / 10000 ms gets truncated.
Yep, that's definitely what it's doing. What's strange though is that the
one shot timer using the same function works correctly, so it must use a
different timing mechanism.
"Chris P. [MVP]" <ms...@chrisnet.net> wrote in message
news:vex0xrb7ajzr$.1gcx2ryt2cluq.dlg@40tude.net...
You can always use IReferenceClock.
IReferenceClock* pRefClock;
CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,IID_IReferenceC
lock,(void**)&pRefClock);
Now you can use Advise() or AdvisePeriodic() method.
--
It is practically impossible to teach good programming to students that have
had a prior exposure to BASIC: as potential programmers they are mentally
mutilated beyond hope of regeneration. (Edsger Dijkstra 1930-2002)