SDK programming notes - timer articles
Two timer API discussions
The SetTimer function is used to create a timer, and the KillTimer function is used to destroy a timer. The timer belongs to the system resources and is completely destroyed in time.
SETTIMER's function prototype as follows: uint_ptr settimer (HWND HWND, UINT_PTR NIDEVENT, UINT UELAPSE, TIMERPROC LPTIMERFUNC); where hWnd is a window handle associated with Timer, this window must be all threads that call setTimer; if hWnd is NULL, no windows, Timer is associated and the Nidevent parameter is ignored that nidevent is the identity of the Timer, is a non-zero value; if hwnd is NULL is ignored; if hwnd is non-NULL, there is a Timer identified by the Timer, this time SetTimer calls will replace the original Timer with new Timer. The Timer ID and window are related, two different windows can have the same TIEMR uLapse specified in milliseconds in milliseconds, range from 1 milliseconds to 4,294,967,295 milliseconds (nearly 50 days), this value indicates that Windows gives the program every time. Send a WM_TIMER message. LptimerFunc is a pointer to a callback function, commonly known as TimerFunc; if lptimerfunc is null, the system will send a WM_TIMER message to the application queue; if the lptimerfunc specifies a value, DEFWINDOWPROC will call this LPTIMERFUNC to call the callback function pointed to by this lptimerfunc, so therefore Even if you use TimerProc instead of processing WM_TIMER, you need to distribute messages to the window.
About the return value of SetTimer: If hwnd is null, return the value for the newly established Timer ID, if hwnd is non-null, return a non-0 integer, return 0 if the setTimer call fails
KillTimer's function prototype is: Bool KillTimer (hwnd hwnd, uint_ptr uidevent); parameter meaning is with SetTimer. About KillTimer affects the impact of the remaining unprocessed WM_TIMER messages in the message queue, the MSDN and Programming Windows statements are totally opposite. MSDN say very simply: The KillTimer function does not remove WM_TIMER messages already posted to the message queue and 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, your program will never receive a "Wandering Wandering" wm_timer message after calling KillTimer
About WM_TIMER message
WPARAM is the id of the timer; if multiple timers need to be set, different timer IDs are used for each timer. The value of WPARAM will vary from the WM_TIMER message delivered to the window. LParam is a pointer to TimerProc, and if the TimerProc is specified when calling setTimer, LPARAM is 0 (ie null). You can process this message by providing a WM_TIMER CASE during the window, or the default window process calls the three methods of the TimerProc specified in SetTimer to handle three methods of using the timer using the timer.
If the timer is used during the entire execution of the program, the setTimer is typically called before processing the WM_CREATE message or before the message cycle in WinMain is processed, and when the WM_DESTROY message is processed or RETURN is called before the message cycle in WinMain. According to the parameters in the settimer, there are three ways to use the timer.
Method 1: When you call setTimer, specify the window handle hWnd, Nidevent Specify the timer ID, and set the lptimerfunc null to do not use TimerProc; process the WM_TIMER message during the window. When you call KillTimer, use the HWND and IDs specified in SetTimer. It is best to use #define definition Timer ID, for example:
#define id_timer 1 setTimer (hwnd, id_timer, 1000, null); killtimer (hwnd, id_timer);
Method 2: When calling setTimer, specify the window handle hWnd, Nidevent specifies the timer ID, and the lptimerfunc parameter is not specified as a pointer to the TimerProc function. This method uses the TIMERPROC function (name can be self-determined) to process the WM_TIMER message:
Void Callback TimerProc (HWND HWND, UINT MESSAGE, UINT ITIMERID, DWORD DWTIME) {// Handling WM_TIMER message}
TimerProc parameter hWnd is the window handle specified when calling SetTimer. Windows only gives the WM_TIMER message to TimerProc, so the message parameter is always equal to WM_Timer. The ITIMERID value is the timer ID, the DWTIMER value is a value compatible with the return value from the GetTickCount function. This is the number of milliseconds passing after the startup of Windows. When using this method, the form of correlation function call is:
Settimer (HWND, ID_TIMER, 1000, TimerProc); KillTimer (HWND, Id_Timer);
Method 3: When calling setTimer, the window handle (NULL) is not specified, and the ITIMERID parameter is naturally ignored, and the LPTIMERFUNC is not specified as the TimerProc in NULL. As mentioned above, the return value of the setTimer is the ID of the newly established timer, and you need to save this ID for the KillTimer destroyed timer. Of course, KillTimer's HWND parameters are also set to NULL. This method also handles the WM_TIMER message with TimerProc.
Uint_ptr itimerid; itimerid = setTimer (NULL, 0, 1000, TimerProc); KillTimer (NULL, ITIMERID);
The advantage of using this method is not to specify the timer ID itself, so you don't have to worry about using the wrong ID.
Use multiple timers
Using multiple timers As long as the different ID is specified when the timer is established. For example, the method described above:
#define timer_sec 1 # define timer_min 2 Then use two settimers to set two timers: SetTimer (hwnd, timer_sec, 1000, null); setTimer (hwnd, timer_min, 60000, null); WM_TIMER's processing is shown below: Case WM_TIMER: Switch (wparam) {copy timer_sec: // Treatment Break every second; Case Timer_min: // Treatment Break is handled every minute;} return 0; change the timing interval of the timer
If you want to set a already existing timer to a different time interval, you can simply call Settimer again with different time values.
Is the timer precise?
The timer is not accurate. There are two reasons:
Cause 1: The Windows Timer is a relatively simple expansion of the timer at the hardware and the ROM BIOS architecture. Back to the previous MS-DOS program Word environment for Windows, the application can achieve clock or timer by intercepting the BIOS interrupt of Timer Tick. Some programs written by MS-DOS have intercepted this hardware interrupt to implement clock and timer. These interrupts are generated once every 54.915 milliseconds, or about 18.2 times per second. This is the result of the original IBM PC's microprocessor frequency value 4.772720 MHz is obtained by 218. In Windows 98, the timer has a resolution of 55 milliseconds as the PC timer. In Microsoft Windows NT, the resolution of the timer is 10 milliseconds. The Windows application cannot be higher than those of these resolution (under Windows 98, 18.2 per second, under Windows NT, approximately 100 times per second) receives the WM_TIMER message. The time interval specified in SetTimer is always an integer multiple of Tick number after the tail. For example, the intervals of 1000 milliseconds are divided by 54.925 milliseconds, resulting in 18.207 Tick, 18 Ticks after the tail, which is actually 989 milliseconds. Each Tick generates a WM_TIMER message for each Tick. It can be seen that the timer cannot send a WM_TIMER message in strict accordance with the specified time interval, which always takes a few milliseconds.
Even if you ignore the difference in these milliseconds, the timer is still inaccurate. See the reason 2: WM_TIMER message is placed in normal message queues, and other messages are arranged together, so if the interval is specified in SetTimer to 1000 milliseconds, then the program will not be guaranteed to receive one per 1000 milliseconds or 989 milliseconds. WM_TIMER message. If the execution of other programs is more than one second, your program will not receive any WM_TIMER messages during this period. In fact, Windows handles the WM_TIMER message very similar to the processing of the WM_Paint message, which is low priority, and the program only receives them when there are no other messages in the message queue. WM_TIMER is also similar to the other aspect and WM_PAINT: Windows cannot continuously put multiple WM_TIMER messages to the message queue, but combine excess WM_TIMER messages into one message. Therefore, the application does not receive multiple such messages at a time, although two WM_TIMER messages may be obtained in a short period of time. The application cannot determine the number of WM_TIMER messages "missing" caused by this processing mode. It can be seen that the WM_TIMER message cannot be handled in time, and the delay in the message queue may not be calculated in milliseconds in the message queue.
From the above two points, you cannot count by counting a second one second in the handle of WM_TIMER. If you want to implement a clock program, you can use the system's time function such as getLocalTime, and in the clock program, the timer's role is the timing call getLocalTime to get a new time and refresh the clock screen, of course, this refresh is equal to or less than 1 second . THE END