The ettimer function is used to create a timer, and the killtimer function is used to destroy a timer. The timer is a system resource and should be destroyed in time after use.
SettimerThe function prototype is as follows:
Uint_ptr settimer (hwnd, uint_ptr nidevent, uint uelapse, timerproc lptimerfunc );
Where
Hwnd is the window handle associated with timer. This window must be owned by the thread that calls settimer. If hwnd is null, There is no window associated with timer and the nidevent parameter is ignored.
Nidevent is the identifier of the timer. It is a non-zero value. If hwnd is null, it is ignored. If hwnd is not null and a timer already exists in the window associated with the timer, the settimer call will replace the original timer with a new timer. The timer identifier is related to the window. Two different windows can have the same tiemr as nidevent.
Uelapse is a time interval value specified in milliseconds, ranging from 1 ms to 4,294,967,295 ms (nearly 50 days). This value indicates how often windowsProgramSend the wm_timer message.
Lptimerfunc is a pointer to a callback function, commonly known as timerfunc. If lptimerfunc is null, the system sends a wm_timer message to the application queue. If lptimerfunc specifies a value, defwindowproc calls the callback function pointed to by lptimerfunc when processing the wm_timer message. Therefore, even if timerproc is used instead of wm_timer, messages need to be sent to the window.
Settimer return value: If hwnd is null, the return value is the ID of the newly created timer. If hwnd is not null, a non-zero integer is returned. If settimer fails to be called, 0 is returned.
KilltimerThe function prototype is bool killtimer (hwnd, uint_ptr uidevent). The parameter meaning is the same as settimer.
For the effect of killtimer on the remaining unprocessed wm_timer messages in the message queue, msdn and programming are completely different on Windows. The killtimer function does not remove wm_timer messages already posted to the message queue. petzold says the killtimer call purges the message queue of any pending wm_timer messages. your program will never receive a stray wm_timer message following a killtimer call. (killtimer eliminates any unprocessed wm_timer messages in the message queue. After killtimer is called, your program will never receive a "Wandering" wm_timer message)
Wparam is the timer ID. If you need to set multiple timers, different timer IDs are used for each timer. The value of wparam varies with the wm_timer message passed to the window.
Lparam is the pointer to timerproc. If timerproc is not specified when settimer is called (the parameter value is null), lparam is 0 (that is, null ).
You can provide a wm_timer case in the window process to process the message, or the default Window Process will call the timerproc specified in settimer to process the wm_timer message.
Three methods of using a timer |
If a timer is used during the entire execution of the program, settimer is usually called before processing the wm_create message or the message loop in winmain, call killtimer before processing a wm_destroy message or returning a message loop in winmain. There are three ways to use a timer, depending on the parameters in settimer.
Method 1: When settimer is called, specify the window handle hwnd, specify the timer ID in nidevent, and set lptimerfunc to null so that timerproc is not used. wm_timer messages are processed during the window process. When calling killtimer, use the hwnd and ID specified in settimer. It is best to use # define to define the timer ID, for example:
# Define id_timer 1 Settimer (hwnd, id_timer, 1000, null ); Killtimer (hwnd, id_timer ); |
Method 2: When settimer is called, specify the window handle hwnd and the timer ID in nidevent. The lptimerfunc parameter is not null and is specified as the pointer of the timerproc function. This method uses the timerproc function (names can be customized) to process wm_timer messages:
Void callback timerproc (hwnd, uint message, uint itimerid, DWORD dwtime) { // Process the wm_timer message } |
The hwnd parameter of timerproc is the window handle specified when settimer is called. Windows only sends the wm_timer message to timerproc, so the message parameter is always equal to wm_timer. The itimerid value is the timer ID, and the dwtimer value is compatible with the return value from the gettickcount function. This is the number of milliseconds that have elapsed since Windows was started. When using this method, the relevant function call form is:
Settimer (hwnd, id_timers, 1000, timerproc ); Killtimer (hwnd, id_timer ); |
Method 3: When settimer is called, the window handle (null) is not specified. The itimerid parameter is ignored naturally. lptimerfunc is not null and is specified as the timerproc pointer. As mentioned above in the settimer discussion, the returned value of settimer is the ID of the newly created timer. You need to save this ID for killtimer to destroy the timer. Of course, the hwnd parameter of killtimer is also set to null. This method also uses timerproc to process wm_timer messages.
Uint_ptr itimerid; Itimerid = settimer (null, 0,1000, timerproc ); Killtimer (null, itimerid ); |
The advantage of using this method is that you do not have to specify the timer ID, so you do not have to worry about using the wrong id.
To use multiple timers, you only need to specify different IDs when creating the timer. For example:
# Define timer_sec 1 # Define timer_min 2 Use two settimer to set two Timers: Settimer (hwnd, timer_sec, 1000, null ); Settimer (hwnd, timer_min, 60000, null ); Wm_timer processing is as follows: Case wm_timer: Switch (wparam) { Case timer_sec: // Processing once per second Break; Case timer_min: // Processing every minute Break; } Return 0; |
Change the timer Interval |
If you want to set an existing timer to a different interval, you can simply call settimer again with different time values.
The timer is not accurate. There are two reasons:
cause 1: The Windows timer is a relatively simple expansion of the timer in the hardware and rom bios architecture. Back in Windows's previous MS-DOS writing environment, applications can implement a clock or timer through BIOS interruptions called Timer tick by interceptors. Some programs written for the MS-DOS themselves intercept this hardware interrupt for clock and timer. These interruptions occur every 54.915 milliseconds, or about 18.2 times per second. This is the result of the 4.772720 MHz division of the original ibm pc microprocessor. In Windows 98, the timer has the same resolution of 55 milliseconds as the PC timer. In Microsoft Windows NT, the timer resolution is 10 ms. Windows applications cannot receive wm_timer messages at a frequency higher than these resolutions (18.2 times per second in Windows 98 and about 100 times per second in Windows NT. The time interval specified in settimer is always an integer multiple of the tick count after the tail truncation. For example, if the interval of 1000 ms is divided by 54.925 ms, 18.207 tick is obtained and 18 tick is taken at the end of the screenshot, which is actually 989 Ms. For each interval less than 55 milliseconds, each tick will generate a wm_timer message.
as you can see, the timer cannot send the wm_timer message strictly at the specified interval. The difference is always several milliseconds.
The timer is still inaccurate even if the difference in milliseconds is ignored. Please refer to reason 2:
The wm_timer message is placed in a normal message queue and arranged together with other messages. Therefore, if the interval specified in settimer is 1000 milliseconds, therefore, it is not guaranteed that the program will receive a wm_timer message every 1000 ms or 989 Ms. If the execution event of other programs exceeds one second, during this period, your program will not receive any wm_timer message. In fact, Windows processes wm_timer messages very similar to wm_paint messages. These two messages are of low priority, and the program receives them only when there are no other messages in the message queue.
Wm_timer is also similar to wm_paint: Windows cannot continuously put multiple wm_timer messages into the message queue, but combines redundant wm_timer messages into one message. Therefore, the application will not receive multiple such messages at a time, although two wm_timer messages may be obtained in a short time. The application cannot determine the number of wm_timer message "Omissions" caused by this processing method.
It can be seen that wm_timer messages cannot be processed by the application in a timely manner, and the delay of wm_timer in the message queue may not be calculated in milliseconds.
From the preceding two points, you cannot use the one-second count method when processing wm_timer. If you want to implement a clock program, you can use a system time function such as getlocaltime. In the clock program, the timer function is to call getlocaltime regularly to obtain a new time and refresh the clock screen, of course, the interval for refreshing is equal to or less than 1 second.
From: http://www.cppblog.com/ivenher/archive/2012/07/17/19969.html#183913