1. preface.
We know that in Windows, you can call the settimer function to applyProgramAssign a timer. When
After a time interval is specified, Windows sends a wm_timer message to the application at a specified time.
So that the application can implement many time-related actions.
However, it should be noted that the wm_timer message sent by the system to the application is not asynchronous, and this message is
Put it in a regular message queue and sort it with other messages. Therefore, even if we call settimer ()
The time interval is set to 1000 milliseconds, but the application may not necessarily receive
Wm_timer message. If another program is busy for more than one second
You cannot receive any wm_timer message within the specified time.
Obviously, this situation is fatal for applications that require precise time intervals (such as some monitoring programs ).
. Fortunately, some mechanisms are hidden in windows so that we can get the exact timer service.
2. system timer.
The Windows system. DRV Driver provides a few little-known system timer functions (these functions
The number is not written to Windows. h, but is output by system. DRV). These functions can help us obtain the precision.
The timer service, that is, the system timer. The most important of these are createsystemtimer () and
Killsystemtimer (), the two functions allow us to install the callback function of the asynchronous timer (callback), there are
Similar to intercepting an int 8 interrupt handler in a DOS environment. This callback is truly asynchronous and completely avoided.
Windows message tool is of great significance. In fact, Microsoft Excel and Windows comm
The driver uses the system timer, and the general timer installed by settimer () is also the system timer.
.
The two functions are prototype as follows:
Word createsystemtimer (wmsecinterval, lpfntimerproc );
Word wmsecinterval;/* interval in milliseconds. The system calls a callback function at this time.
*/
Farproc lpfn timerproc;/* pointer to the callback function */
Word killsystemtimer (htimer );
Word htimer;/* system timer handle to be released */
Createsystemtimer () is used to install a system timer callback function.
This callback function is called at the specified time interval of wmsecinterval. Of course, the specified callback frequency is also
Limited. Like settimer (), the number of calls to the callback function per second cannot exceed 18.2, that is, wmsecinterval>
55. This function returns a system timer handle. If the installation fails, null is returned. Killsystemtimer ()
Used to cancel an installed system timer htimer. If the operation succeeds, the system returns the result. If an error occurs, the system returns the parameter passed to it.
Htimer.
3. Precautions for using the system timer.
Although the system timer callback function is not an interrupt handler, it is called by the interrupt handler directly.
Consider it as an interruptionCode. This determines that you must pay attention to the following issues during use:
(1). the callback function should include as few code as possible so that the function with frequent callback does not occupy too much CPU.
. Generally, a system timer is used to monitor or set values of certain variables.
(2). Because the callback function is an interrupted code, most Windows API function calls are not applicable, only
Several simple functions can still be used, such as postmessage (), getcurrenttask (), and messagebeep ()
.
(3) because the callback function is directly called by the interrupt handler, the function must be placed in a fixed code segment.
And the DS register must be loaded before the call. This can be done by the makeprocinstance () function of the form replacement function.
In addition, because these two functions are not provided in windows. H (that is, the default input library for Windows does not include these two functions ),
This must be linked before the call. This can adopt the dynamic link at runtime, that is, through getmodulehandle () and
Getprocaddress (). You can also use the imports statement in the program module definition file.
The createsystemtimer () and killsystemtimer () must be described as external functions in the program source file. This article provides
The second solution is used.
4. An example.
This article provides a simple example to illustrate how the system timer works.
In this example, we have installed a callback function called every second, which generates a beep. To
To test the system timer, we specially compiled a loop statement for a long time. In this cycle
Settimer ()
The timer installed usually does not work (because Windows is a non-preemptive system), and the system we install
The timer can still beep every second.
This example is successfully debugged in msvc ++ 1.5 and runs well.
// Initiate EMT. c
# Include <windows. h>
Extern word winapi createsystemtimer (word wtimeout, farproc lpfntimerproc );
Extern word winapi killsystemtimer (word htimer );
Void far pascal_export mytimerproc (void );
Word setupsystemtimer (word wtimeout );
Bool clearsystem timer (word htm );
Farproc fptimerproc = NULL;
Word htimer = NULL;
Char szappname [] = "systemtimer ";
Int Pascal winmain (handle hinstance, handle hprevinstance,
Lpstr lpsz1_param, int ncmdshow)
{
Wndclass WC;
Hwnd hwndmain;
Int I, J;
Hcursor hcursave;
If (hprevinstance = NULL ){
WC. lpszmenuname = NULL; WC. lpszclassname = szappname; WC. hinstance = hinstance; WC. hicon = loadicon (null, idi_application );
WC. hcursor = loadcursor (null, idc_arrow );
WC. hbrbackground = (hbrush) color_window + 1;
WC. Style = 0; WC. lpfnwndproc = defwindowproc;
WC. cbclsextra = 0; WC. cbwndextra = 0;
If (! Registerclass (& WC ))
Return (0 );
}
If (hwndmain = createwindow (szappname,
Szappname, ws_overlappedwindow,
Cw_usedefault, cw_usedefault,
Cw_usedefault, cw_usedefault,
Null, null, hinstance, null) = NULL)
Return (0 );
Showwindow (hwndmain, ncmdshow );
Update window (hwndmain );
Fptimerproc = makeprocinstance (farproc) mytimerproc, hinstance );
If (htimer = setupsystemtimer (1000) = null {
MessageBox (hwndmain, "set system timer error ",
Szappname, mb_iconexclamation: mb_ OK );
Return 0;
}
Hcursave = setcursor (loadcursor (null, idc_wait ));
For (I = 0; I <10000; I ++)
For (j = 0; j <10000; j ++)
Setcursor (hcursave );
Clearsystemtime (htimer );
}
Word setupsystemtime (word wtimeout)
{
Word HTM;
If (HTM = createsystemtimer (wtimeout, fptimerproc) = NULL ){
Fptimerproc = NULL:
Return null
} Else return HTM;
}
Bool clearsystemtimer (word htm)
{
If (HTM ){
If (killsystemtimer (HTM )! = 0)
Return false;
Htm = NULL;
}
Return true
Voidfar pascal_export mytimerproc (void)
{
Messagebeep (0 );
}
////////////////////////////////////
// Initiate EMT. Def
Name systemtimer
Description 'System timer'
Exetype windows
Stub 'winstub'
Code Preload
Data preload movable multiple
Heapsize 1024
Stacksize 8192
Exports mytimerproc
Imports createsystemtimer = system. createsystemtimer
Killsystemtimer = system. killsystemtimer