在Windows中使用精确计时器_第1页
在Windows中使用精确计时器_第2页
在Windows中使用精确计时器_第3页
在Windows中使用精确计时器_第4页
在Windows中使用精确计时器_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在Windows中使用精确计时器 1.前言。 我们知道,在Windows中,可以通过调用SetTimer函数为应用程序分配一个计时器。当指定了一个时间间隔以后,Windows系统将每隔指定的时间向应用发送一条WM_TIMER消息,从而使应用程序能够实现许多与时间相关的动作。 然而需要指出的是,由系统发给应用程序的WM_TIMER消息并不是异步的,这条消息被放在常规的消息队列中,并与其它消息一起排序。因此,即使我们在调用SetTimer()时设定了1000毫秒的时间间隔,应用程序却不一定保证每隔一秒钟接受到一条WM_TIMER消息,如果另一个程序的忙碌时间超过一秒钟,那么我们的应用程序在那段时间

2、内就不能接收到任何WM_TIMER消息。 显然,这种情况的存在对那些需要精确时间间隔的应用(如某些监控程序)来说是致命的。所幸的是,在Windows中隐藏着某些机制,使得我们能够获得精确计时器服务。2.系统计时器. 在Windows的SYSTEM.DRV驱动程序中提供了几个鲜为人知的系统计时器函数(这几个函数未写入Windows.h中,但却被SYSTEM.DRV输出了),这几个函数可以帮助我们获得精确计时器服务,即系统计时器。这其中最重要的是CreateSystemTimer()和KillSystemTimer(),这两个函数允许我们安装异步计时器的回调函数(Callback),有些类似于在D

3、OS环境中截取INT 8中断处理程序。这个回调是真正异步的,完全避开了Windows的消息工具,因而具有重要意义。事实上,Microsoft Excel和Windows COMM驱动程序都用到了系统计时器,而由SetTimer()安装的一般计时器也是由系统计时器来实现的。这两个函数的原型如下:WORD CreateSystemTimer(wMsecInterval,lpfnTimerProc);WORD wMsecInterval; /*以毫秒为单位的时间间隔,系统将每隔此时间调用一 次回调函数*/FARPROC lpfn TimerProc;/*指向回调函数的指针*/WORD KillSys

4、temTimer(hTimer);WORD hTimer;/*欲释放的系统计时器句柄*/其中,CreateSystemTimer()用于安装一个系统计时器回调函数,SYSTEM INT8处理程序将按wMsecInterval指定的时时间间隔调用此回调函数。当然,这个指定的回调频率也是有限的,同SetTimer()一样,每秒钟调用回调函数次数不能超过18.2次,即wMsecInterval>55。该函数返回一个系统计时器句柄。若安装失败,则返回NULL。KillSystemTimer()则用于撤销一个已安装的系统计时器hTimer。若成功,则返回;出错则返回传给它的参数hTimer。3.使

5、用系统计时器应注意的问题。系统计时器回调函数虽然不是中断处理程序,但由于它直接被中断处理程序调用,因此也必将它看作中断代码。这也就决定了在使用过程中必须注意以下几个问题:(1).在回函数中应包括尽量少的代码,以使得频繁回调的该函数不至于占用太多的CPU时间。一般情况下,系统计时器总是用来监视或设置某些变量的值。(2).由于该回调函数属于中断代码,因此大多数Windows API函数调用都不适用了,只有几个简单的函数仍然可以使用,如PostMessage(),GetCurrentTask()和MessageBeep()等。(3).由于该回调函数由中断处理程序直接调用,因此该函数必须放在一个固定的

6、代码段中,并且调用前必须装载DS寄存器,这可由形实替换函数MakeProcInstance()来做到。另外,由于这两个函数在Windows.h中没有给出(即Windows缺省输入库不含此两函数),因此在调用之前必须进行链接。这可采用运行时动态链接,即通过GetModuleHandle()和GetProcAddress()来链接;也可在程序模块定义文件中用IMPORTS语句来引入,此时则必须在程序源文件中说明CreateSystemTimer()和KillSystemTimer()为外部函数。本文给出的例子采用第二种方案。4.一个例子。本文最后给出一个简单的例子,以说明系统计时器是如何工作的。在

7、本例中,我们安装了一个每秒钟调用一次的回调函数,该回调函数发出一声蜂鸣。为了测试该系统计时器,我们特意编写了一段较长时间的循环语句。在这段循环中,由SetTimer()安装的通常计时器是不能工作的(因为Windows是一个非抢先的系统),而我们安装的系统计时器仍然能每隔一秒钟发出一声蜂鸣。该例子在MSVC+1.5中调试通过,运行良好。/SystemT.c#include<windows.h>extern WORD WINAPI CreateSystemTimer(WORD wTimeOut,FARPROC lpfnTimerProc);extern WORD WINAPI Kill

8、SystemTimer(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 lpszCmdParam,int nCmd

9、Show)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.lpfnWndpr

10、oc =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(hWndM

11、ain);fpTimerProc=MakeProcInstance(FARPROC)MyTimerProc,hInstance);if(hTimer=SetUpSystemTimer(1000)=NULLMessageBox(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

12、(hcurSave);ClearSystemTime(hTimer);WORD SetUpSystemTime(WORD wTimeOut)WORD hTm;if(hTm=CreateSystemTimer(wTimeOut,fpTimerProc)=NULL)fpTimerProc=NULL:return NULLelse return hTm;BOOL ClearSystemTimer(WORD hTm)if(hTm)if(KillSystemTimer(hTm)!=0)return FALSE;hTm=NULL;return TRUEvoidFAR PASCAL_export MyTimerProc(void)MessageBeep(0);/SystemT.defNAME SystemTimerDESCRIPTIONSystem TimerEXETYPE

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论