在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當(dāng)前位置:雨林木風(fēng)下載站 > 技術(shù)開發(fā)教程 > 詳細(xì)頁面

VB高精度計(jì)時器編程的討論

VB高精度計(jì)時器編程的討論

更新時間:2022-05-14 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

     VB記時器編程的討論 在很多場合下編程(例如工業(yè)控制、游戲)中需要比較精確的記時器,本文討論的是在VB下實(shí)現(xiàn)記時器的若干方法以及它們的精度控制問題。 在VB中最常用的是Timer控件,它的設(shè)置和使用都非常方便,理論上它的記時精度可以達(dá)到1ms(毫秒)。但是眾所周知的,實(shí)際上Timer在記時間隔小于50ms之下是精度是十分差的。它只適用于對于精度要求不太高的場合。 這里作者要介紹的是兩中利用Windows API函數(shù)實(shí)現(xiàn)精確記時的方法。第一中方法是利用高性能頻率記數(shù)(作者本人的稱呼)法。利用這種方法要使用兩個API函數(shù)QueryPerformanceFrequency和QueryPerformanceCounter。QueryPerformanceFrequency函數(shù)獲得高性能頻率記數(shù)器的震蕩頻率,該函數(shù)的定義如下:  

Private Declare Function QueryPerformanceFrequency Lib "kernel32" _
              (lpFrequency As LARGE_INTEGER) As Long
函數(shù)中的數(shù)據(jù)結(jié)構(gòu)LARGE_INTEGER定義如下:
Type LARGE_INTEGER
    lowpart As Long
    highpart As Long
End Type

調(diào)用該函數(shù)后,函數(shù)會將系統(tǒng)頻率記數(shù)器的震蕩頻率保存到lpPerformanceCount中,其中低位保存到lowpart中,高位保存到highpart中。但是現(xiàn)在的Windows沒有使用到hightpart(系統(tǒng)頻率記數(shù)器的震蕩頻率與計(jì)算機(jī)的主頻無關(guān),我在幾臺機(jī)上做過驗(yàn)證,都是lowpart為1193180,highpart為0)。
QueryPerformanceCounter函數(shù)獲得系統(tǒng)頻率記數(shù)器的震蕩次數(shù),函數(shù)的定義如下

Private Declare Function QueryPerformanceCounter Lib "kernel32" _
        (lpPerformanceCount As LARGE_INTEGER) As Long

獲得記時器震蕩次數(shù)保存在lpPerformanceCount中。
顯然,如果首先獲得利用QueryPerformanceFrequency函數(shù)獲得頻率記數(shù)器的震蕩頻率,然后在執(zhí)行某個程序段之前調(diào)用QueryPerformanceCounter函數(shù)獲得頻率記數(shù)器的震蕩次數(shù),在程序段結(jié)束再調(diào)用QueryPerformanceCounter函數(shù)獲得頻率記數(shù)器的震蕩次數(shù),將兩次獲得的震蕩次數(shù)相減后再除以震蕩頻率就獲得的了兩次間隔之間的時間(以秒為單位)。如果在程序中建立一個循環(huán),在循環(huán)中不停的調(diào)用QueryPerformanceCounter獲得頻率記數(shù)器的震蕩次數(shù)并同先前的頻率記數(shù)器的震蕩次數(shù)相減,將結(jié)果除以頻率記數(shù)器的震蕩頻率,如果達(dá)到一定的時間就執(zhí)行某個任務(wù),這樣就實(shí)現(xiàn)了一個比較精確的記時器的功能。

另外的一種精確記時器的功能是利用多媒體記時器函數(shù)(這也是作者的定義,因?yàn)檫@個系列的函數(shù)是在Winmm.dll中定義并且是為媒體播放服務(wù)的)。
實(shí)現(xiàn)多媒體記時器首先要定義timeSetEvent函數(shù),該函數(shù)的定義如下:

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

函數(shù)定義中參數(shù)uDelay定義延遲時間,以毫秒為單位,該參數(shù)相當(dāng)于Timer控件的Interval屬性。參數(shù)uResolution定義記時精度,如果要求盡可能高的精度,要將該參數(shù)設(shè)置為0;參數(shù)lpFunction定義了timeSetEvent函數(shù)的回調(diào)函數(shù)的地址。參數(shù)dwUser定義用戶自定義的回調(diào)值,該值將傳遞給回調(diào)函數(shù)。參數(shù)uFlags定義定時類型,如果定義為Time_OneShot,則只會在當(dāng)達(dá)到uDelay定義的時間后調(diào)用回調(diào)函數(shù)一次,如果定義為TIME_PERIODIC,則在每次達(dá)到定時時間后調(diào)用回調(diào)函數(shù)。
如果函數(shù)調(diào)用成功,在系統(tǒng)中建立了一個多媒體記時器對象,每當(dāng)經(jīng)過一個uDelay時間后lpFunction指定的函數(shù)都會被調(diào)用。同時函數(shù)返回一個對象標(biāo)識,如果不再需要記時器則必須要使用timeKillEvent函數(shù)刪除記時器對象。
由于Windows是一個多任務(wù)的操作系統(tǒng),因此基于API調(diào)用的記時器的精度都會受到其它很多因素的干擾。到底這兩中記時器的精度如何,我們來使用以下的程序進(jìn)行驗(yàn)證:
設(shè)置三種記時器(Timer控件、高性能頻率記數(shù)、多媒體記時器)。將它們的定時間隔設(shè)置為10毫秒,讓它們不停工作直到達(dá)到一個比較長的時間(比如60秒),這樣記時器的誤差會被累計(jì)下來,然后同實(shí)際經(jīng)過的時間相比較,就可以得到它們的精度。
下面是具體的檢測程序。
首先建立一個工程文件,在Form1中加入一個Timer控件,兩個CommandButton控件和三個TextBox控件,然后在Form1的代碼窗口中加入以下代碼


Option Explicit

Private 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)
        '如果時鐘震動次數(shù)超過10毫秒的次數(shù)則刷新Text1的顯示
        If lagTick2.lowpart - lagTick1.lowpart > lTen Then
            lagTick1 = lagTick2
            iCountStart = iCountStart - 0.01
            Text1.Text = Format$(iCountStart, "00.00")
        End If
        DoEvents
    Wend
End Sub

Private Sub Command2_Click()
    EndCount
End Sub

Private 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
     
    '獲得系統(tǒng)板上時鐘頻率
    QueryPerformanceFrequency lim
     
    '將頻率除以1000就的出時鐘1毫秒震動的次數(shù)
    lMSFreq = (lim.highpart * 2 ^ 16) \ 1000 + lim.lowpart \ 1000
    Timer1.Interval = 10
    Timer1.Enabled = False
End Sub

Private Sub Timer1_Timer()
    TimerCount = TimerCount - 0.01
    Text3.Text = Format$(TimerCount, "00.00")
    If TimerCount <= 0 Then
Timer1.Enabled = False
End If
End Sub
在Project中加入一個Module,然后在其中加入以下代碼:
Option Explicit

Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type

Public Declare Function QueryPerformanceCounter Lib "kernel32" _
(lpPerformanceCount As LARGE_INTEGER) As Long
Public Declare Function QueryPerformanceFrequency Lib "kernel32" _
(lpFrequency As LARGE_INTEGER) As Long
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
Public Declare Function timeKillEvent Lib "winmm.dll" (ByVal uID As Long) As Long
Public Declare Function GetTickCount Lib "kernel32" () As Long

Public lMSFreq As Long
Public TimerCount As Single
Public lmmCount As Single
Public lTimeID As Long
Public actTime1 As Long
Public actTime2 As Long
Public iCountStart As Single

Dim iCount As Single

'timeSetEvent的回調(diào)函數(shù)
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 If
End Sub
Sub EndCount()
iCount = iCountStart
iCountStart = 0
timeKillEvent lTimeID
actTime2 = GetTickCount - actTime1
With Form1
.Command1.Enabled = True
.Command2.Enabled = False
.Timer1.Enabled = False

.Text1 = "計(jì)數(shù)器記時" + Format$((60 - iCount), "00.00") + " " _
+ "實(shí)際經(jīng)過時間" + Format$((actTime2 / 1000), "00.00")
.Text2 = "計(jì)數(shù)器記時" + Format$((60 - lmmCount), "00.00") + " " _
+ "實(shí)際經(jīng)過時間" + Format$((actTime2 / 1000), "00.00")
.Text3 = "計(jì)數(shù)器記時" + Format$((60 - TimerCount), "00.00") + " " _
+ "實(shí)際經(jīng)過時間" + Format$((actTime2 / 1000), "00.00")
End With
End Sub


運(yùn)行程序,點(diǎn)擊“開始倒記時”按鈕開始倒記時,可以看到兩種API記時器工作基本正常,文本框中的倒記時顯示流暢,而Timer控件的時間顯示相比之下卻不堪重負(fù),十分緩慢。按“停止記時”按鈕就可以停止倒記時,由圖1可以看到,兩種API記時器的累計(jì)誤差在2‰以下,考慮到系統(tǒng)原因和處理記時顯示的時間,這個誤差基本是可以接受的,而且經(jīng)過作者的多次檢測,誤差都在3‰以下。而Timer控件的誤差簡直是無法接受的。

在運(yùn)行程序時作者還發(fā)現(xiàn)一個問題,如果在倒記時時拖動窗口,文本框中的顯示都會停止,而當(dāng)停止窗口拖放后,多媒體記時器顯示會跳過這段時間記時,而其它兩種記時器顯示倒記時卻還是從原來的時間倒數(shù)。這說明多媒體記時器是在獨(dú)立的線程中運(yùn)行的,不會受到程序的影響。

綜合上面的介紹和范例,我們可以看到,如果要建立高精度的記時器,使用多媒體記時器是比較好的選擇。而高性能頻率記數(shù)法比較適合計(jì)算某個耗時十分短的過程所消耗的時間(例如分析程序中某個被多次調(diào)用的程序段執(zhí)行時間以優(yōu)化程序),因?yàn)楫吘垢咝阅茴l率記數(shù)的理論可以達(dá)到微秒級別。Timer控件雖然精度比上面兩者差很多,但是它使用方便,在要求不高的場合它還是最佳選擇。
以上程序在Windows 98中文版,VB6下運(yùn)行通過。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 男女超爽视频免费播放| 久久久久xxxx| 欧美激情第四页| 精品人妻一区二区三区四区在线 | 男女激烈动态图| 日韩手机在线观看视频| 手机看片日韩国产| 久久婷婷国产91天堂综合精品| 成人性做爰片免费视频| 69久久久久久| 亚洲 高清 成人 动漫| 国产欧美123| 日本一本在线视频| gogogo高清免费观看在线视频| 777精品久无码人妻蜜桃| 欧美日韩在线免费观看视频| 日本精品一区二区三区四区| 农民人伦一区二区三区| 国产不卡的av| 日本黄大片一区二区三区| 99久久久无码国产精品6| 黄色国产一级视频| 激情成人开心网| 国内精品国产三级国产99| 在线看免费毛片| 亚洲少妇久久久| 激情五月婷婷久久| 男人女人黄一级| wwwwxxxx日韩| xxx国产在线观看| 天天操狠狠操夜夜操| 日本中文字幕观看| 中国黄色片一级| 超碰在线资源站| 一二三av在线| 久久人妻无码一区二区| av在线免费观看国产| 97视频在线免费| 精品视频免费在线播放| 亚欧无线一线二线三线区别| 国产激情在线观看视频| 日本888xxxx| 天天操精品视频| 久久99国产精品一区| 国内精品国产三级国产99| 青青草视频在线免费播放| 日本成年人网址| 超碰在线公开97| 在线无限看免费粉色视频| 隔壁人妻偷人bd中字| 各处沟厕大尺度偷拍女厕嘘嘘| 天堂社区在线视频| 精品国产三级a∨在线| 东北少妇不带套对白| 狠狠热免费视频| 国产九九九视频| 成熟丰满熟妇高潮xxxxx视频| 激情视频综合网| 日韩 欧美 自拍| av片中文字幕| 四虎1515hh.com| 久久久久久久久久久免费视频| 中文久久久久久| 超级碰在线观看| 中国黄色片免费看| 欧美视频在线第一页| 亚洲视频一二三四| 国产手机免费视频| 欧美女同在线观看| 9久久9毛片又大又硬又粗| 亚洲自拍第三页| jizzjizz国产精品喷水| 亚洲综合伊人久久| 午夜免费一区二区| 亚洲人精品午夜射精日韩| 青娱乐精品在线| 国产一区二区视频免费在线观看| 400部精品国偷自产在线观看| 国产综合免费视频| 日韩国产成人无码av毛片| 三级在线视频观看| a√天堂在线观看| 国产一二三在线视频| 亚洲自拍偷拍一区二区三区| 亚洲欧美日韩三级| av在线无限看| 欧美私人情侣网站| 免费成人在线视频网站| 97超碰国产精品| 国产一二三四五| 91蝌蚪视频在线| 在线能看的av网站| 91亚洲精品久久久蜜桃借种| 欧美日韩一区二区在线免费观看 | 亚洲欧美一二三| 日本精品一区在线| 777一区二区| 毛片毛片毛片毛| 午夜视频在线观| 99精品视频国产| 中文字幕在线乱| 青青在线视频免费观看| 亚洲中文字幕无码一区二区三区| 天天综合中文字幕| 免费观看黄色大片| 欧美a级免费视频| 国产性生活免费视频| 五月丁香综合缴情六月小说| 蜜臀av无码一区二区三区| 黄色成人在线看| 人人干人人视频| 超碰超碰在线观看| 午夜影院免费版| 亚洲熟妇无码av在线播放| 秋霞无码一区二区| 成年人视频观看| 欧美伦理片在线观看| 一二三av在线| a级黄色小视频| 国产男女激情视频| 亚洲一区二区三区四区精品| 992tv快乐视频| 青青草成人免费在线视频| 国产自偷自偷免费一区| 国产又大又长又粗又黄| 97超碰人人澡| 欧美日韩一区二区三区69堂| 日本黄色a视频| 日本毛片在线免费观看| 欧美一级视频在线| 欧美日韩二三区| 一区二区三区入口| 成人精品视频在线播放| 午夜在线观看av| 99久久免费观看| 中文字幕第100页| 日韩精品一区二区免费| 日本特黄a级片| 免费看黄在线看| 99中文字幕在线| 欧美激情国产精品日韩| 好吊色视频988gao在线观看| 国产理论在线播放| 成人区一区二区| 第一区免费在线观看| 91av资源网| 日韩极品视频在线观看| 亚洲第一中文av| 亚洲熟女乱色一区二区三区| 狠狠精品干练久久久无码中文字幕| 国产视频在线视频| 97超碰国产精品| 欧美a级黄色大片| 中文字幕国产高清| 性chinese极品按摩| 无码aⅴ精品一区二区三区浪潮| 99久热在线精品视频| 99日在线视频| 五月婷婷六月丁香激情| 男女视频一区二区三区| 国产96在线 | 亚洲| 国产一区二区三区在线免费| 日韩精品视频网址| 91亚洲一区二区| 国产福利精品一区二区三区| 国产aaaaa毛片| 五月天婷婷激情视频| 亚洲精品乱码久久久久久自慰| 欧美深夜福利视频| 人妻少妇精品久久| 2018日日夜夜| 九色在线视频观看| 精品无码国模私拍视频| 亚洲中文字幕无码专区| 成熟丰满熟妇高潮xxxxx视频| 九一国产精品视频| 欧美日韩在线中文| 亚洲中文字幕久久精品无码喷水| 乱妇乱女熟妇熟女网站| 久久久久久久久久福利| 波多野结衣作品集| 一道本视频在线观看| 手机免费av片| 999热精品视频| 精品视频在线观看一区二区| 国产毛片视频网站| 色一情一乱一伦一区二区三区日本 | 天天久久综合网| 国产欧美综合一区| 欧美日韩精品在线一区二区| 日韩a在线播放| 五月天视频在线观看| 亚洲色图都市激情| 欧美大片在线播放| 久久人人爽av| 免费高清一区二区三区| 国产日韩成人内射视频| 九九久久久久久| 国产极品尤物在线| 99国产精品久久久久久|