This section describes how an application might use the timer services. First, the application calls the timeGetDevCaps function to determine the minimum and maximum resolution supported by the timer services. Before setting up any timer events, the application uses timeBeginPeriod to establish the minimum timer resolution it will use, as shown in the following code fragment:
#define TARGET_RESOLUTION 1 // Try for 1-millisecond accuracy
TIMECAPS tc;
UINT wTimerRes;
if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
{
// Error; application can't continue
}
wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
timeBeginPeriod(wTimerRes);
To start the timer event, the application specifies the amount of time before the callback occurs, the required resolution, the address of the callback function, and user data to supply with the callback. The application might use a function like the following to start a one-time timer event:
UINT SetTimerCallback(NPSEQ npSeq, // Sequencer data
UINT msInterval) // Event interval
{
npSeq->wTimerID = timeSetEvent(
msInterval, // Delay
wTimerRes, // Resolution (global variable)
OneShotCallback, // Callback function
(DWORD)npSeq, // User data
TIME_ONESHOT ); // Event type (one-time)
if(! npSeq->wTimerID)
return ERR_TIMER;
else
return ERR_NOERROR;
}
The following callback function resides in a fixed code segment in a DLL. It is limited to calling those functions that are interrupt-callable. The TimerIntRoutine procedure it calls also resides in a fixed code segment.
void FAR PASCAL
OneShotTimer(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
NPSEQ npSeq; // Pointer to sequencer data
npSeq = (NPSEQ)dwUser;
npSeq->wTimerID = 0; // Invalidate timer id, since no longer in use
TimerIntRoutine(npSeq); // Handle interrupt-time tasks
}
Before freeing the DLL that contains the callback function, the application cancels any outstanding timers. To cancel one timer event, it might call the following function:
void DestroyTimer(NPSEQ npSeq)
{
if(npSeq->wTimerID) // If timer event is pending
{
timeKillEvent(npSeq->wTimerID); // Cancel the event
npSeq->wTimerID = 0;
}
}
Finally, to cancel the minimum timer resolution it established, the application calls timeEndPeriod as follows:
timeEndPeriod(wTimerRes);