




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
.VB.NET论坛 |搜索 |给我来信 首页| 代码中心| 开发技巧| 问答| 开发文档| 下载| 站点连接| VB.NET专栏|My Blog| Windows API 窗口/控件 网络与Internet 文件操作 数据库 图形图像 多媒体 系统 注册表操作 杂项 ASP/VBScript VBA DirectX&游戏 系统 控件 数据库 网络/Internet 图形图像 多媒体 窗口 字符串 键盘、鼠标、打印 杂项 控件 系统 数据库 文件操作 Windows API VBA 网络/Internet VB_IDE 注册表 数学运算 杂项 ASP/VBScript ActiveX控件/Com 数据库 文件、驱动器操作 图形图像&多媒体 网络/Internet Windows系统 VB IDE VBA/OLE AutoMation 窗口及基本控件 .NET 技术 开发控件 程序开发库 网友作品VB高精度计时器编程的讨论VB记时器编程的讨论 在很多场合下编程(例如工业控制、游戏)中需要比较精确的记时器,本文讨论的是在VB下实现记时器的若干方法以及它们的精度控制问题。 在VB中最常用的是Timer控件,它的设置和使用都非常方便,理论上它的记时精度可以达到1ms(毫秒)。但是众所周知的,实际上Timer在记时间隔小于50ms之下是精度是十分差的。它只适用于对于精度要求不太高的场合。 这里作者要介绍的是两中利用Windows API函数实现精确记时的方法。第一中方法是利用高性能频率记数(作者本人的称呼)法。利用这种方法要使用两个API函数QueryPerformanceFrequency和QueryPerformanceCounter。QueryPerformanceFrequency函数获得高性能频率记数器的震荡频率,该函数的定义如下: Private Declare Function QueryPerformanceFrequency Lib kernel32 _ (lpFrequency As LARGE_INTEGER) As Long函数中的数据结构LARGE_INTEGER定义如下:Type LARGE_INTEGER lowpart As Long highpart As LongEnd Type调用该函数后,函数会将系统频率记数器的震荡频率保存到lpPerformanceCount中,其中低位保存到lowpart中,高位保存到highpart中。但是现在的Windows没有使用到hightpart(系统频率记数器的震荡频率与计算机的主频无关,我在几台机上做过验证,都是lowpart为1193180,highpart为0)。QueryPerformanceCounter函数获得系统频率记数器的震荡次数,函数的定义如下Private Declare Function QueryPerformanceCounter Lib kernel32 _ (lpPerformanceCount As LARGE_INTEGER) As Long获得记时器震荡次数保存在lpPerformanceCount中。显然,如果首先获得利用QueryPerformanceFrequency函数获得频率记数器的震荡频率,然后在执行某个程序段之前调用QueryPerformanceCounter函数获得频率记数器的震荡次数,在程序段结束再调用QueryPerformanceCounter函数获得频率记数器的震荡次数,将两次获得的震荡次数相减后再除以震荡频率就获得的了两次间隔之间的时间(以秒为单位)。如果在程序中建立一个循环,在循环中不停的调用QueryPerformanceCounter获得频率记数器的震荡次数并同先前的频率记数器的震荡次数相减,将结果除以频率记数器的震荡频率,如果达到一定的时间就执行某个任务,这样就实现了一个比较精确的记时器的功能。另外的一种精确记时器的功能是利用多媒体记时器函数(这也是作者的定义,因为这个系列的函数是在Winmm.dll中定义并且是为媒体播放服务的)。实现多媒体记时器首先要定义timeSetEvent函数,该函数的定义如下:Public Declare Function timeSetEvent Lib winmm.dll (ByVal uDelay As Long, ByVal _ uResolution As Long, ByVal lpFunction As Long, ByVal dwUser As Long, _ ByVal uFlags As Long) As Long函数定义中参数uDelay定义延迟时间,以毫秒为单位,该参数相当于Timer控件的Interval属性。参数uResolution定义记时精度,如果要求尽可能高的精度,要将该参数设置为0;参数lpFunction定义了timeSetEvent函数的回调函数的地址。参数dwUser定义用户自定义的回调值,该值将传递给回调函数。参数uFlags定义定时类型,如果定义为Time_OneShot,则只会在当达到uDelay定义的时间后调用回调函数一次,如果定义为TIME_PERIODIC,则在每次达到定时时间后调用回调函数。如果函数调用成功,在系统中建立了一个多媒体记时器对象,每当经过一个uDelay时间后lpFunction指定的函数都会被调用。同时函数返回一个对象标识,如果不再需要记时器则必须要使用timeKillEvent函数删除记时器对象。由于Windows是一个多任务的操作系统,因此基于API调用的记时器的精度都会受到其它很多因素的干扰。到底这两中记时器的精度如何,我们来使用以下的程序进行验证:设置三种记时器(Timer控件、高性能频率记数、多媒体记时器)。将它们的定时间隔设置为10毫秒,让它们不停工作直到达到一个比较长的时间(比如60秒),这样记时器的误差会被累计下来,然后同实际经过的时间相比较,就可以得到它们的精度。下面是具体的检测程序。首先建立一个工程文件,在Form1中加入一个Timer控件,两个CommandButton控件和三个TextBox控件,然后在Form1的代码窗口中加入以下代码Option ExplicitPrivate Sub Command1_Click() Dim lagTick1 As LARGE_INTEGER Dim lagTick2 As LARGE_INTEGER Dim lTen As Long Command2.Enabled = True Command1.Enabled = False iCountStart = 60 lmmCount = 60 TimerCount = 60 actTime1 = GetTickCount lTimeID = timeSetEvent(10, 0, AddressOf TimeProc, 1, 1) Timer1.Enabled = True lTen = 10 * lMSFreq Call QueryPerformanceCounter(lagTick1) lagTick2 = lagTick1 While iCountStart 0 Call QueryPerformanceCounter(lagTick2) 如果时钟震动次数超过10毫秒的次数则刷新Text1的显示 If lagTick2.lowpart - lagTick1.lowpart lTen Then lagTick1 = lagTick2 iCountStart = iCountStart - 0.01 Text1.Text = Format$(iCountStart, 00.00) End If DoEvents WendEnd SubPrivate Sub Command2_Click() EndCountEnd SubPrivate Sub Form_Load() Dim lim As LARGE_INTEGER Text1.Text = 60.00 Text2.Text = 60.00 Text3.Text = 60.00 Command1.Caption = 开始倒记时 Command2.Caption = 停止记时 Command2.Enabled = False 获得系统板上时钟频率 QueryPerformanceFrequency lim 将频率除以1000就的出时钟1毫秒震动的次数 lMSFreq = (lim.highpart * 2 16) 1000 + lim.lowpart 1000 Timer1.Interval = 10 Timer1.Enabled = FalseEnd SubPrivate Sub Timer1_Timer() TimerCount = TimerCount - 0.01 Text3.Text = Format$(TimerCount, 00.00) If TimerCount = 0 Then Timer1.Enabled = False End IfEnd Sub在Project中加入一个Module,然后在其中加入以下代码:Option ExplicitType LARGE_INTEGER lowpart As Long highpart As LongEnd TypePublic Declare Function QueryPerformanceCounter Lib kernel32 _ (lpPerformanceCount As LARGE_INTEGER) As LongPublic Declare Function QueryPerformanceFrequency Lib kernel32 _ (lpFrequency As LARGE_INTEGER) As LongPublic Declare Function timeSetEvent Lib winmm.dll (ByVal uDelay As Long, ByVal _ uResolution As Long, ByVal lpFunction As Long, ByVal dwUser As Long, _ ByVal uFlags As Long) As LongPublic Declare Function timeKillEvent Lib winmm.dll (ByVal uID As Long) As LongPublic Declare Function GetTickCount Lib kernel32 () As LongPublic lMSFreq As LongPublic TimerCount As SinglePublic lmmCount As SinglePublic lTimeID As LongPublic actTime1 As LongPublic actTime2 As LongPublic iCountStart As SingleDim iCount As SingletimeSetEvent的回调函数Sub TimeProc(ByVal uID As Long, ByVal uMsg As Long, ByVal dwUser As Long, _ ByVal dw1 As Long, ByVal dw2 As Long) Form1.Text2.Text = Format$(lmmCount, 00.00) lmmCount = lmmCount - 0.01 If lmmCount = 0 Then iCountStart = 60 lmmCount = 60 TimerCount = 60 EndCount End IfEnd SubSub EndCount() iCount = iCountStart iCountStart = 0 timeKillEvent lTimeID actTime2 = GetTickCount - actTime1 With Form1 .Command1.Enabled = True .Command2.Enabled = False .Timer1.Enabled = False .Text1 = 计数器记时 + Format$(60 - iCount), 00.00) + _ + 实际经过时间 + Format$(actTime2 / 1000), 00.00) .Text2 = 计数器记时 + Format$(60 - lmmCount), 00.00) + _ + 实际经过时间 + Format$(actTime2 / 1000), 00.00) .Text3 = 计数器记时 + Format$(60 - TimerCount), 00.00) + _ + 实际经过时间 + Format$(actTime2 / 1000), 00.00) End WithE
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 张家口市中石化2025秋招面试半结构化模拟题及答案电气仪控技术岗
- 大唐电力通辽市2025秋招性格测评常考题型与答题技巧
- 2025年潜水科目考试题及答案
- 石嘴山市中石油2025秋招笔试模拟题含答案行测综合英语
- 七台河市中石油2025秋招网申填写模板含开放题范文
- 中国移动汉中市2025秋招半结构化面试模拟30问及答案
- 黄冈市中石化2025秋招面试半结构化模拟题及答案油田勘探开发岗
- 那曲市中石油2025秋招面试半结构化模拟题及答案油气储运与管道岗
- 岳阳市中石化2025秋招面试半结构化模拟题及答案炼化装置操作岗
- 上饶市中石化2025秋招面试半结构化模拟题及答案炼油工艺技术岗
- 文学类文本阅读2026届高三9月名校模考试分类汇编五
- 2025年9月20日云南省直机关遴选公务员笔试真题及答案解析
- 合同纠纷民事起诉状模板示例
- 招行ai面试题库大全及答案
- 投标服务响应应急方案(3篇)
- 第4课 探究智慧农业应用领域 课件【教科版】《信息科技》八年级上册
- 无人机航拍课件
- 2025支付宝财经内容生态报告
- 水务集团招聘考试笔试试题及答案
- 35kv变电运维协议合同
- 2025年四川三州圆科技开发有限公司招聘考试笔试试题(含答案)
评论
0/150
提交评论