计时-在windows中使用精确计时器

上传人:kms****20 文档编号:41523417 上传时间:2018-05-29 格式:DOC 页数:6 大小:30KB
返回 下载 相关 举报
计时-在windows中使用精确计时器_第1页
第1页 / 共6页
计时-在windows中使用精确计时器_第2页
第2页 / 共6页
计时-在windows中使用精确计时器_第3页
第3页 / 共6页
计时-在windows中使用精确计时器_第4页
第4页 / 共6页
计时-在windows中使用精确计时器_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《计时-在windows中使用精确计时器》由会员分享,可在线阅读,更多相关《计时-在windows中使用精确计时器(6页珍藏版)》请在金锄头文库上搜索。

1、计时计时- -在在 WindowsWindows 中使用精确计时器中使用精确计时器在 Windows 中使用精确计时器 -作者:黎旭昌 来源: 类别:Visual C+ 日期:2001.08.29 今日/总浏览: 2/235 1.前言。 我们知道,在 Windows 中,可以通过调用 SetTimer 函数为应用程序分配一个计时器。当指定了一个时间间隔以后,Windows 系统将每隔指定的时间向应用发送一条 WM_TIMER 消息,从而使应用程序能够实现许多与时间相关的动作。 然而需要指出的是,由系统发给应用程序的 WM_TIMER 消息并不是异步的,这条消息被放在常规的消息队列中,并与其它消

2、息一起排序。因此,即使我们在调用 SetTimer()时设定了 1000 毫秒的时间间隔,应用程序却不一定保证每隔一秒钟接受到一条 WM_TIMER 消息,如果另一个程序的忙碌时间超过一秒钟,那么我们的应用程序在那段时间内就不能接收到任何 WM_TIMER 消息。 显然,这种情况的存在对那些需要精确时间间隔的应用(如某些监控程序)来说是致命的。所幸的是,在 Windows 中隐藏着某些机制,使得我们能够获得精确计时器服务。 2.系统计时器. 在 Windows 的 SYSTEM.DRV 驱动程序中提供了几个鲜为人知的系统计时器函数(这几个函数未写入 Windows.h 中,但却被 SYSTEM

3、.DRV 输出了),这几个函数可以帮助我们获得精确计时器服务,即系统计时器。这其中最重要的是 CreateSystemTimer()和 KillSystemTimer(),这两个函数允许我们安装异步计时器的回调函数(Callback),有些类似于在 DOS 环境中截取 INT 8 中断处理程序。这个回调是真正异步的,完全避开了 Windows 的消息工具,因而具有重要意义。事实上,Microsoft Excel 和 Windows COMM 驱动程序都用到了系统计时器,而由 SetTimer()安装的一般计时器也是由系统计时器来实现的。这两个函数的原型如下: WORD CreateSystem

4、Timer(wMsecInterval,lpfnTimerProc); WORD wMsecInterval; /*以毫秒为单位的时间间隔,系统将每隔此时间调用一 次回调函数*/ FARPROC lpfn TimerProc;/*指向回调函数的指针*/ WORD KillSystemTimer(hTimer); WORD hTimer;/*欲释放的系统计时器句柄*/ 其中,CreateSystemTimer()用于安装一个系统计时器回调函数,SYSTEM INT8 处理程序将按 wMsecInterval 指定的时时间间隔调用此回调函数。当然,这个指定的回调频率也是有限的,同SetTimer(

5、)一样,每秒钟调用回调函数次数不能超过 18.2 次,即wMsecInterval55。该函数返回一个系统计时器句柄。若安装失败,则返回 NULL。KillSystemTimer()则用于撤销一个已安装的系统计时器 hTimer。若成功,则返回;出错则返回传给它的参数hTimer。 3.使用系统计时器应注意的问题。 系统计时器回调函数虽然不是中断处理程序,但由于它直接被中断处理程序调用,因此也必将它看作中断代码。这也就决定了在使用过程中必须注意以下几个问题: (1).在回函数中应包括尽量少的代码,以使得频繁回调的该函数不至于占用太多的 CPU 时间。一般情况下,系统计时器总是用来监视或设置某些

6、变量的值。 (2).由于该回调函数属于中断代码,因此大多数 Windows API 函数调用都不适用了,只有几个简单的函数仍然可以使用,如PostMessage(),GetCurrentTask()和 MessageBeep()等。 (3).由于该回调函数由中断处理程序直接调用,因此该函数必须放在一个固定的代码段中,并且调用前必须装载 DS 寄存器,这可由形实替换函数 MakeProcInstance()来做到。另外,由于这两个函数在 Windows.h 中没有给出(即 Windows 缺省输入库不含此两函数),因此在调用之前必须进行链接。这可采用运行时动态链接,即通过GetModuleHan

7、dle()和 GetProcAddress()来链接;也可在程序模块定义文件中用 IMPORTS 语句来引入,此时则必须在程序源文件中说明 CreateSystemTimer()和 KillSystemTimer()为外部函数。本文给出的例子采用第二种方案。 4.一个例子。 本文最后给出一个简单的例子,以说明系统计时器是如何工作的。在本例中,我们安装了一个每秒钟调用一次的回调函数,该回调函数发出一声蜂鸣。为了测试该系统计时器,我们特意编写了一段较长时间的循环语句。在这段循环中,由 SetTimer()安装的通常计时器是不能工作的(因为 Windows 是一个非抢先的系统),而我们安装的系统计时

8、器仍然能每隔一秒钟发出一声蜂鸣。该例子在MSVC+1.5 中调试通过,运行良好。 /SystemT.c #include extern WORD WINAPI CreateSystemTimer(WORD wTimeOut,FARPROC lpfnTimerProc); extern WORD WINAPI KillSystemTimer(WORD hTimer); void FAR PASCAL_export MyTimerProc(void); WORD SetUpSystemTimer(WORD wTimeOut); BOOL ClearSystem Timer(WORD hTm); F

9、ARPROC fpTimerProc=NULL; WORD hTimer=NULL; char szAppName=“SystemTimer“; int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance, LPSTR lpszCmdParam,int nCmdShow) WNDCLASS wc; HWND hWndMain; int I,j; HCURSOR hcurSave; if(hPrevInstance=NULL) wc.lpszMenuName =NULL; wc.lpszClassName =szAppName; wc.hIn

10、stance =hInstance; wc.hIcon =LoadIcon(NULL,IDI_APPLICATION); wc.hCursor =LoadCursor(NULL,IDC_ARROW); wc.hbrBackground =(HBRUSH)COLOR_WINDOW+1; wc.style =0; wc.lpfnWndproc =DefWindowProc; wc.cbClsExtra =0; wc.cbWndExtra =0; if(!RegisterClass( if(hWndMain=CreateWindow(szAppName, szAppName,WS_OVERLAPPE

11、DWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL)=NULL) return(0); ShowWindow(hWndmain,nCmdShow); Update Window(hWndMain); fpTimerProc=MakeProcInstance(FARPROC)MyTimerProc,hInstance); if(hTimer=SetUpSystemTimer(1000)=NULL MessageBox(hwndMain,“Set System Tim

12、er Error“, szAppName,MB_ICONEXCLAMATION:MB_OK); return 0; hcurSave=SetCursor(LoadCursor(NULL,IDC_WAIT); for(I=0;I10000;I+) for(j=0;j10000;j+) SetCursor(hcurSave); ClearSystemTime(hTimer); WORD SetUpSystemTime(WORD wTimeOut) WORD hTm; if(hTm=CreateSystemTimer(wTimeOut,fpTimerProc)=NULL) fpTimerProc=N

13、ULL: return NULL else return hTm; BOOL ClearSystemTimer(WORD hTm) if(hTm) if(KillSystemTimer(hTm)!=0) return FALSE; hTm=NULL; return TRUE voidFAR PASCAL_export MyTimerProc(void) MessageBeep(0); / /SystemT.def NAME SystemTimer DESCRIPTIONSystem Timer EXETYPE WINDOWS STUB WINSTUB CODE PRELOAD DATA PRELOAD MOVABLE MULTIPLE HEAPSIZE 1024 STACKSIZE 8192 EXPORTS MyTimerProc IMPORTS CreateSystemTimer=SYSTEM.CREATESYSTEMTIMER KillSystemTimer=SYSTEM.KILLSYSTEMTIMER

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号