Win32 Timer Callback Function

Processing WM_TIMER Messages Outside the Windows Procedure

© Guy Lecky-Thompson

An alternative method for processing WM_TIMER interrupts using a TimerProc timer callback function defined by the Win32 API.

Introduction

Windows message processing usually happens in the following way - Windows generates a message, and sends it to the application thread. The WinMain function in that thread is waiting for incoming messages, and sends them to the associated windows procedure for processing.

This windows procedure contains a large set of case statements in a one big switch construct where the message is evaluated. Generally, these are WM_ messages such as WM_CREATE, WM_DESTROY, WM_PAINT and WM_COMMAND. One such WM_ message is WM_TIMER which is used to process interrupts generated by user defined timers. Processing these is dealt with in the Using the Win32 Timer APO article.

This article details an alternative approach - using a callback function which the WM_TIMER message is passed to rather than the windows procedure of the calling thread.

The Message Loop

Inside the WinMain function of a Windows application, there is a busy waiting loop which looks something like:

while (GetMessage (&msg, NULL, 0, 0))
{
  TranslateMessage (&msg) ;
  DispatchMessage (&msg) ;
}

The msg parameter is a MSG structure, and contains the Windows message details - the identifier (WM_), the WPARAM and LPARAM. Each Windows message contains these three pieces of information, among others, and each Window has a thread that processes them. This applies equally to child window controls, application windows and other elements.

The DispatchMessage function sends the message to the appropriate place, which in the case of an application is the windows procedure specified in the creation parameters of the instance of the class used to create the application. In other words, when the application registered the class associated with itself, it also told Windows where to send the messages, whenever the DispatchMessage function was called.

However, this behavior can be overridden by the use of callback functions.

Creating the Timer

When we create a timer with a callback function, we use a slightly different version of the SetTimer function:

UINT myTimer = SetTimer ( hwnd, ID_TIMER, 60000, TimerProc );

The fourth parameter specifies the address of the function to call whenever the DispatchMessage function is required to send a WM_TIMER message to the application. It overrides the normal behavior which sends the message to the windows procedure.

The WM_TIMER Message and TimerProc

When we create a callback function to be used with timers, we define it as follows:

VOID CALLBACK TimerProc ( HWND hParent, UINT uMsg, UINT uEventID, DWORD dwTimer )
{
  // Process timer message
}

The uMsg parameter will always contain WM_TIMER, while the uEventID is equal to the identifier given in the call to SetTimer (and not the return value from SetTimer). The dwTimer parameter contains a number equal to the number of milliseconds since Windows was started. It is equal to calling GetTickCount, and is the Windows time at which the WM_TIMER interrupt was generated.


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



Comments
May 8, 2008 5:26 AM
Guest :
When you have a callback function defined, in which thread does the func run? the main message loop or the thread that register the SetTimer or a thread from system pool?
Page:
1 Comment:

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