In VC programming, with SetTimer can define a timer, to the time, the response to OnTimer message, but this timer accuracy is too low. If you need a higher precision timer (accurate to 1ms), you can use the following high-precision multimedia timer for code optimization, can achieve millisecond accuracy, and easy to use. First, include the header file "Mmsystem.h" and the library file "Winmm.lib".
AlthoughWin95 visual development tools such asvc, delphi, c++ Builder and so on have a dedicated timer control timer, and easy to use, can achieve a certain timing function, but the minimum timing accuracy of only 55ms, and the timer messages in the multitasking operating system priority is very low, can not be timely response, often can not meet the real-time control environment applications. But microsoft company in win32 The API library has provided the user with a set of underlying functions for high-precision timing, which, if used properly, can be timed to 1ms. This timing accuracy, for general real-time system control can fully meet the requirements. Now will be by c++ builder   4.0 provides a set of time-dependent primary interface functions (function names, parameters, functions, and win32 API basically the same) description is as follows:
1. DWORD timegettime (void)
Returns the number of milliseconds that have elapsed since Windows started. The maximum value is 232, approximately 49.71 days.
2. mmresult timesetevent (
UINT Udelay,
UINT uresolution,
Lptimecallback Lptimeproc,
DWORD Dwuser,
UINT fuevent)
This function sets a timed callback event, which can be a one-time event or a recurring event. Once the event is activated, the specified callback function is invoked, the identifier code of the event is returned after success, otherwise NULL is returned . The parameters are described as follows:
Udelay: Specifies the period of the event in milliseconds.
uresolution: Specify the precision of the delay in milliseconds, the smaller the value the higher the timer event resolution. The default value is 1ms.
Lptimeproc: Point to a callback function.
Dwuser: Store user-provided callback data.
fuevent: Specifies the Timer event type :
Time_oneshot:Only one event is generated after udelay milliseconds
Time_periodic: generates events periodically every udelay millisecond.
3. mmresult timekillevent (UINT utimerid)
The function cancels a specified timer callback event. Utimerid identifies the event to be canceled ( the identifier returned by the timeSetEvent function). Returns Timerr_noerror if successful , or Mmsyserr_invalparam if the timer time does not exist .
4. callback function
void CALLBACK Timeproc (
UINT UID,
UINT umsg,
DWORD Dwuser,
DWORD DW1,
DWORD dw2);
The function is an application-defined callback function that is called when a timer event occurs. Timeproc is a placeholder for an application-defined function name. Use this function
It is important to note that it can only invoke the following limited set of API functions:PostMessage,timegetsystemtime, timegettime, timesetevent, Timekillevent
,midioutshortmsg, midioutlongmsg,OutputDebugString. Also, do not use API functions that take a long time to complete, and the program is as short as possible.
You can use the above set of functions to complete the timing and control of millisecond-level accuracy ( to add header files mmsystem.h to your program when used in C++builder ). Due to the timing control
System to a few milliseconds, the timer event will occupy a large amount of CPU time and systems resources, so in the premise of satisfying the control requirements, should try to increase the value of the parameter uresolution. and
and the timer real-time control function is completed to release as soon as possible.
Note the following questions:
First, the parameters of the callback function can not be wrong, otherwise it may cause the program to collapse;
Second, the event call period Udelay cannot be less than the event processing time, otherwise it will cause the program to crash;
Third, passing parameters to the callback function by Dwuser
The routines are as follows:
Mmresult G_wtimerid = 0;
callback function, parameter cannot be wrong
void CALLBACK Cdsisiidlg::sendfun (uint Wtimerid, UINT msg, DWORD Dwuser, DWORD dwl, DWORD dw2)
{
cdsisiidlg* Pdcpackerdlg = (cdsisiidlg*) dwuser;
...
}
BOOL Cdsisiidlg::createtimer ()
{
Timecaps TC;
UINT Wtimerres;
Setting up a multimedia timer
if (Timegetdevcaps (&tc,sizeof (timecaps))!=timerr_noerror)//Apply a multimedia timer to the machine
return false;
Get machine-allowed time intervals (typically up to 1 milliseconds)
Wtimerres=min (Max (tc.wperiodmin,1), Tc.wperiodmax);
Timer starts to work
Timebeginperiod (Wtimerres);
The callback function Timerback () is called every 6 milliseconds, and Wtimerid is the timer ID. The Time_periodic table is periodically called, and thetime_oneshot table produces only one event
G_wtimerid = timeSetEvent (6, Wtimerres, (Lptimecallback) Sendfun, (DWORD) this, time_periodic);
if (G_wtimerid = = 0)
return false;
return true;
}
Remove Timer
void Cdsisiidlg::D estroytimer ()
{
if (G_wtimerid)
{
Timekillevent (G_wtimerid);
G_wtimerid = 0;
}
}
For the use of Windows multimedia Timers under QT
In the qtimer source Analysis (take windows implementation as an example ), we see the use of qt in windows for timers:
For zero interval,QT does not use the system timer
For cases with non-zero intervals
When the interval is less than 20ms and the system supports multimedia timers, use the multimedia timer
Otherwise, use the normal timer
Qt This strategy should be able to meet our needs very well, but QTCN on the previous netizen is more expected to call the system's multimedia timer directly. In this case, you still try to write, write your own Timer class
Code
The code is still relatively simple, and the header file mmtimer.h as follows:
#ifndef Mmtimer_h
#define Mmtimer_h
#include
#include
Class Mmtimer:public Qobject
{
Q_object
Public
explicit Mmtimer (int interval, qobject *parent = 0);
~mmtimer ();
Signals:
void timeout ();
Public Slots:
void Start ();
void Stop ();
friend void WINAPI CALLBACK mmtimer_proc (UINT, uint, dword_ptr, dword_ptr, dword_ptr);
Private
int m_interval;
int m_id;
};
#endif//Mmtimer_h
Source files mmtimer.cpp as follows:
#include "Mmtimer.h"
#include
#ifdef __mingw32__//w32api Bug
#define Time_kill_synchronous 0x0100
#endif
void WINAPI CALLBACK Mmtimer_proc (UINT Timerid, uint, dword_ptr user, dword_ptr, dword_ptr)
{
Mmtimer *t = reinterpret_cast (user);
Emit T->timeout ();
}
Mmtimer::mmtimer (int interval, qobject *parent):
Qobject (parent), M_interval (interval), m_id (0)
{
}
Mmtimer::~mmtimer ()
{
Stop ();
}
void Mmtimer::start ()
{
m_id = timeSetEvent (M_interval, 1, Mmtimer_proc, (dword_ptr) This,
time_callback_function | Time_periodic | time_kill_synchronous);
}
void Mmtimer::stop ()
{
if (m_id) {
Timekillevent (m_id);
m_id = 0;
}
}
Description
The above code should not require any explanation:
timesetevent and timekillevent Direct access to MSDN
In addition,MinGW's Win32API package, There is no definition of time_kill_synchronous, the code did a bit of correction
Make sure that the required libraries are properly linked
LIBS + =-lwinmm
Note:MSDN's introduction to timeSetEvent said so (no comment on this )
Note this function is obsolete. New applications should use Createtimerqueuetimer to create a timer-queue timer.
Http://blog.sina.com.cn/s/blog_668aae780101dfij.html
VC + + or QT high-precision multimedia timer