vcmfc定时器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vcmfc定时器相关的知识,希望对你有一定的参考价值。

我现在在做一个程序,里面有一个记时钟(是以秒为单位变化的),和一个移动图像(此图像具有变速功能)。所以有两个settimer,但是做出来的效果是记时钟的变化速度与图像变化速度相同,请高手解决一下,有急用
那两个定时器是同时启动的
怎么在一定时间后停止程序并弹出对话框
怎么避免两个定时器被其他消息同时刷新,否则一刷新连计时器也归零了

看看对你有没有帮助

我们在衡量一个函数运行时间,或者判断一个算法的时间效率,或者在程序中我们需要一个定时器,定时执行一个特定的操作,比如在多媒体中,比如在游戏中等,都会用到时间函数。还比如我们通过记录函数或者算法开始和截至的时间,然后利用两者之差得出函数或者算法的运行时间。编译器和操作系统为我们提供了很多时间函数,这些时间函数的精度也是各不相同的,所以,如果我们想得到准确的结果,必须使用合适的时间函数。现在我就介绍windows下的几种常用时间函数。1:Sleep函数使用:sleep(1000),在Windows和Linux下1000代表的含义并不相同,Windows下的表示1000毫秒,也就是1秒钟;Linux下表示1000秒,Linux下使用毫秒级别的函数可以使用usleep。原理:sleep函数是使调用sleep函数的线程休眠,线程主动放弃时间片。当经过指定的时间间隔后,再启动线程,继续执行代码。Sleep函数并不能起到定时的作用,主要作用是延时。在一些多线程中可能会看到sleep(0);其主要目的是让出时间片。精度:sleep函数的精度非常低,当系统越忙它精度也就越低,有时候我们休眠1秒,可能3秒后才能继续执行。它的精度取决于线程自身优先级、其他线程的优先级,以及线程的数量等因素。2:MFC下的timer事件 使用:1.调用函数SetTimer()设置定时间隔,如SetTimer(0,100,NULL)即为设置100毫秒的时间间隔;2.在应用程序中增加定时响应函数OnTimer(),并在该函数中添加响应的处理语句,用来完成时间到时的操作。 原理:同sleep函数一样。不同的是timer是一个定时器,可以指定回调函数,默认为OnTimer()函数。 精度:timer事件的精度范围在毫米级别,系统越忙其精度也就越差。3:C语言下的Time 使用:time_t t;time(&t);Time函数是获取当前时间。 原理:time函数主要用于获取当前时间,比如我们做一个电子时钟程序,就可以使用此函数,获取系统当前的时间。 精度:秒级别4:COM对象中的COleDateTime,COleDateTimeSpan类 使用:COleDateTime start_time = COleDateTime::GetCurrentTime();COleDateTimeSpan end_time = COleDateTime::GetCurrentTime()-start_time;
While(end_time.GetTotalSeconds() < 2)

// 处理延时或定时期间能处理其他的消息
DoSomething()
end_time = COleDateTime::GetCurrentTime-start_time;原理:以上代表延时2秒,而这两秒内我们可以循环调用DoSomething(),从而实现在延时的时候我们也能够处理其他的函数,或者消息。COleDateTime,COleDateTimeSpan是MFC中CTime,CTimeSpan在COM中的应用,所以,上面的方法对于CTime,CTimeSpa同样有效。 精度:秒级别5:C语言下的时钟周期clock() 使用: clock_t start = clock();
Sleep(100);
clock_t end = clock();
double d = (double)(start - end) / CLOCKS_PER_SEC; 原理:clock()是获取计算机启动后的时间间隔。精度:ms级别,对于短时间内的定时或者延时可以达到ms级别,对于时间比较长的定时或者延迟精度还是不够。在windows下CLOCKS_PER_SEC为1000。6:Windows下的GetTickCount()使用: DWORD start = GetTickCount();
Sleep(100);
DWORD end = GetTickCount();原理:GetTickCount()是获取系统启动后的时间间隔。通过进入函数开始定时,到退出函数结束定时,从而可以判断出函数的执行时间,这种时间也并非是函数或者算法的真实执行时间,因为在函数和算法线程不可能一直占用CPU,对于所有判断执行时间的函数都是一样,不过基本上已经很准确,可以通过查询进行定时。GetTickCount()和Clock()函数是向主板Bios要real time clock时间,会有中断产生,以及延迟问题。精度:WindowsNT 3.5以及以后版本精度是10ms,它的时间精度比clock函数的要高,GetTickCount()常用于多媒体中。7:Windows下timeGetTime使用:需要包含Mmsystem.h,Windows.h,加入静态库Winmm.lib.timeBeginPeriod(1);
DWORD start = timeGetTime();
Sleep(100);
DWORD end = timeGetTime();
timeEndPeriod(1);原理:timeGetTime也时常用于多媒体定时器中,可以通过查询进行定时。通过查询进行定时,本身也会影响定时器的定时精度。精度:毫秒,与GetTickCount()相当。但是和GetTickCount相比,timeGetTime可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度, timeBeginPeriod,timeEndPeriod必须成对出现。8:windows下的timeSetEvent使用:还记的VC下的Timer吗?Timer是一个定时器,而以上我们提到几种时间函数或者类型,实现定时功能只能通过轮训来实现,也就是必须另外创建一个线程单独处理,这样会影响定时精度,好在windows提供了内置的定时器timeSetEvent,函数原型为MMRESULT timeSetEvent( UINT uDelay, //以毫秒指定事件的周期
UINT uResolution, //以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms
LPTIMECALLBACK lpTimeProc, //指向一个回调函数
WORD dwUser, //存放用户提供的回调数据
UINT fuEvent )// 标志参数,TIME_ONESHOT:执行一次;TIME_PERIODIC:周期性执行 具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在 lpFunction回调函数中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是:任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,应及时调用timeKillEvent()将之释放。原理:可以理解为代回调函数的timeGetTime精度:毫秒,timeSetEvent可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度, timeBeginPeriod,timeEndPeriod必须成对出现。
9:高精度时控函数QueryPerformanceFrequency,QueryPerformanceCounter使用:LARGE_INTEGER m_nFreq;
LARGE_INTEGER m_nBeginTime;
LARGE_INTEGER nEndTime;
QueryPerformanceFrequency(&m_nFreq); // 获取时钟周期
QueryPerformanceCounter(&m_nBeginTime); // 获取时钟计数
Sleep(100);
QueryPerformanceCounter(&nEndTime);
cout << (nEndTime.QuadPart-m_nBeginTime.QuadPart)*1000/m_nFreq.QuadPart << endl;原理:CPU上也有一个计数器,以机器的clock为单位,可以通过rdtsc读取,而不用中断,因此其精度与系统时间相当。精度:计算机获取硬件支持,精度比较高,可以通过它判断其他时间函数的精度范围。10小结:以上提到常用的9种时间函数,由于他们的用处不同,所以他们的精度也不尽相同,所以如果简单的延时可以用sleep函数,稍微准确的延时可以使用clock函数,GetTickCount函数,更高级的实用timeGetTime函数;简单的定时事件可以用Timer,准确地可以用timeSetEvent;或取一般系统时间可以通time,或者CTime,或者COleDateTime,获取准确的时间可以用clock,或者GetTickCount函数,或者timeGetTime函数,而获取准确地系统时间要使用硬件支持的QueryPerformanceFrequency函数,QueryPerformanceCounter函数。

参考资料:http://hi.baidu.com/deathdog/blog/item/d8d2a37b820745f00ad18738.html

参考技术A 用settimer(1,毫秒数1,NULL);和settimer(2,毫秒数2,NULL);设置2个定时器,设置不同的毫秒数.
添加WM_TIMER事件处理函数
void CTsDBDlg::OnTimer(UINT nIDEvent)

if(nIDEvent==1)
//一号定时器处理代码;
else if(nIDEvent==2)
//二号定时器处理代码;


CDialog::OnTimer(nIDEvent);
本回答被提问者采纳
参考技术B 在/doc/">程序中我们经常要使用定时刷新的功能,典型的应用是在信息管理系统中表单要跟着数据库中的数据变动。MFC提供了定时器来完成这个功能。
在MFC中和定时器相关的有三个函数:
UINT
SetTimer(
UINT
nIDEvent,
UINT
nElapse,
void
(CALLBACK
EXPORT*
lpfnTimer)(
HWND,
UINT,
UINT,
DWORD)
);
afx_msg
void
OnTimer(
UINT
nIDEvent
);
BOOL
KillTimer(
int
nIDEvent
);
参数说明:
UINT
nIDEvent:定时器的ID,给定时器唯一的身份验证,如果在一个/doc/">程序中有多个定时器可以用这个ID来确定是那个定时器发送的消息。
UINT
nElapse:
定义刷新时间,即间隔多长时间刷新一次,单位是毫秒。
void
(CALLBACK
EXPORT*
lpfnTimer)(
HWND,
UINT,
UINT,
DWORD):
这个回调函数中实现刷新时所做的操作,如在数据库中读取数据。但是我们大多数时候不在这里实现,而是在OnTimer中。
函数功能:
SetTimer用来定义一个定时器的属性,如改定时器的ID,刷新时间,处理函数。
OnTimer实际时系统定义消息用来响应WM_TIMER消息,在这里可以实现对多定时器中的各个定时器分别响应,这里才时定时/doc/">程序大展宏图的地方。
字串2
KillTimer用来结束一个定时器。
字串1
下面我们用一个例子来说明定时器的使用:
这个例子用来实现一个简单的功能,就是在一个单/doc/">文档/doc/">程序中,每间隔5秒弹出一个消息框提示“定时器1”,每隔7秒弹出一个消息框提示“定时器2”。
建立单/doc/">文档/doc/">程序略,一路Next。
(1)在resource.h中定义两个定时器的ID
#define
IDTIMER1
1
#define
IDTIMER2
2
(2)在CMainFrame的OnCreate函数中定义两个定时器的属性。
SetTimer(TIMEID1,5000,0);
SetTimer(TIMEID2,7000,0);
(3)
CMainFrame中对WM_TIMER进行响应。
void
CMainFrame::OnTimer(UINT
nIDEvent)

//
TODO:
Add
your
message
handler
code
here
and/or
call
default
switch(nIDEvent)

case
TIMEID1:

AfxMessageBox("定时器1!");
break;

字串1
case
TIMEID2:

AfxMessageBox("定时器2!");
break;

default:
;

CFrameWnd::OnTimer(nIDEvent);

(4)在CMainFrame的析构函数中添加
KillTimer(IDTIMER1);
KillTimer(IDTIMER2);
参考技术C settimer(1,1000,NULL);settimer(2,1000,NULL);函数的2个参数是,每1秒发送一次消息给OnTimer()函数。第一个参数用来区分是哪个定时器。 参考技术D 楼上正解,不过这个timer不是很准的,可以考虑用ace的定时器。

以上是关于vcmfc定时器的主要内容,如果未能解决你的问题,请参考以下文章

如何采用两个定时器的穿行来实现较长时间的定时?

进入定时器中断函数后,定时器数据还在工作吗?

UCOSIII_定时器

JavaScript定时器(延时定时器和间歇定时器)

mysql创建定时器(event),查看定时器,打开定时器,设置定时器时间

STM32 定时器