Use a precise timer in Windows

Source: Internet
Author: User

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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.