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.
Inside the WinMain function of a Windows application, there is a busy waiting loop which looks something like:
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.
When we create a timer with a callback function, we use a slightly different version of the SetTimer function:
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.
When we create a callback function to be used with timers, we define it as follows:
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.