Using the Win32 Timer API

Programming Timed Interrupts and Events in Windows Applications

© Guy Lecky-Thompson

An introduction to the functions provided by the Windows API for controlling timers, reacting to their interrupts, and processing WM_TIMER messages.

Introduction

The Windows operating system follows an event driven artchitecture. In other words, nothing happens unless triggered by an event, be it a keyboard, mouse or system generated event or interrupt. The Windows kernel manages this flow of events, and makes sure that the messages that embody them travel to the correct process for treatment.

The core of any Windows application is the message loop, and the window procedure which processes incoming messages. Given that the majority of events are user or system driven, and that processing only occurs when an application has the 'focus', we sometimes need some way to momentarily get Windows attention to do some processing in an application that is not driven by a user or system event.

There are 2 ways to do this - process in the message loop, during the so-called 'idle' time, or use timers. Timers are easy to manage, predictable, and offer a simple solution for an application that needs to update itself occasionally, rather than constantly.

Creating Timers

A timer is created using the SetTimer funtion, which in the simples form looks like:

UINT SetTimer ( hWnd, nEvent, uElapse, NULL );

The return value is a reference to the timer, used to identify it when the time comes to destroy it. The first parameter is the owner window. The second parameter is usually a constant integer value used to identify messages coming from the timer, while the third parameter is the time, in milliseconds, after which the timer should post an interrupt. So, to set a one-minute timer, we could use code such as:

UINT myTimer = SetTimer ( hwnd, ID_60SECONDS, 60 * 1000, NULL );

The fourth parameter is set to NULL, in this case. It is actually the address of a procedure to call when the timer expires, which is beyond the scope of this article. A timer will keep on generating interrupts until it is destroyed. We assume in the above that hwnd and ID_6°SECONDS are set to meaningful values by the application.

Destroying Timers

A timer is destroyed using the KillTimer function:

BOOL KillTimer ( hWnd, uTimerID );

Success is indicated by a non-zero (TRUE) return value.

Processing the WM_TIMER Message

Between the SetTimer and KillTimer function calls, assuming that everything has gone according to plan, the parent window will receive WM_TIMER messages. Unlike processing menu selections or child window controls, the timer does not send a notification through the WM_COMMAND message. Instead, the WM_TIMER message provides notification interrupts for any timers belonging to the parent windows calling thread.

So, during the window procedure message processing, code such as the following can be inserted:

case WM_TIMER:
switch (wParam)
{
case ID_60SECONDS:
// We processed it, so return 0
return 0;
}
break;

The timer ID, which is not the return value from SetTimer, but the ID given to SetTimer, is received by the message processing loop as the WPARAM part of the MSG structure containing the notification message. The LPARAM contains a pointer to the callback function that can be set as parameter four of the SetTimer function. In the examples we have used here, that value will be set to NULL.

Note that if a callback function is used, the WM_TIMER message is sent to that, rather than the main message queue.


The copyright of the article Using the Win32 Timer API in Windows Programming is owned by Guy Lecky-Thompson. Permission to republish Using the Win32 Timer API must be granted by the author in writing.




Post this Article to facebook Add this Article to del.icio.us! Digg this Article furl this Article Add this Article to Reddit Add this Article to Technorati Add this Article to Newsvine Add this Article to Windows Live Add this Article to Yahoo Add this Article to StumbleUpon Add this Article to BlinkLists Add this Article to Spurl Add this Article to Google Add this Article to Ask Add this Article to Squidoo