在线看毛片视频-国产免费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>
  • 在线观看成人免费| 免费观看国产精品视频| 毛片在线视频播放| 人妻无码一区二区三区四区| 中文字幕第17页| 国产视频一区二区视频| 欧美午夜小视频| 国产欧美久久久久| 在线观看17c| 黑人巨大国产9丨视频| 手机在线观看日韩av| 日本三级黄色网址| 粉色视频免费看| 亚洲 国产 图片| 国产美女视频免费看| 亚洲一区二区图片| 亚洲色图欧美自拍| 国产日产欧美一区二区| 4444亚洲人成无码网在线观看| 91视频成人免费| 日韩精品视频在线观看视频| 亚洲熟妇无码一区二区三区导航| 日韩精品一区二区三区四| 日韩亚洲欧美视频| 成人在线看视频| 五月天中文字幕在线| 日本黄网站色大片免费观看| 少妇高潮毛片色欲ava片| 亚洲乱码中文字幕久久孕妇黑人| 日韩欧美黄色大片| 亚洲成人手机在线观看| 久久99久久久久久| aa在线免费观看| 亚洲 国产 图片| 日本xxxxxxxxxx75| 日日躁夜夜躁aaaabbbb| 国产精品av免费观看| 国产日产欧美视频| 日本一二三区在线| 日韩视频第二页| 无颜之月在线看| 97av视频在线观看| 男人j进女人j| 天天干在线影院| 久久久99精品视频| 密臀av一区二区三区| 国产爆乳无码一区二区麻豆| 午夜免费精品视频| 男人添女人下部高潮视频在观看| 亚洲一级片av| 大香煮伊手机一区| 久久久久久www| 一级黄色高清视频| 在线免费视频a| 我的公把我弄高潮了视频| 涩涩网站在线看| 亚洲午夜精品久久久久久人妖| 四虎成人在线播放| 在线免费av播放| 92看片淫黄大片一级| www.xxx麻豆| 亚洲成年人专区| 校园春色 亚洲色图| 欧美成人黑人猛交| 美女黄色免费看| 亚洲黄色网址在线观看| 亚洲免费av一区| 亚洲 激情 在线| 日韩一级理论片| 日本999视频| www.日本xxxx| 第四色婷婷基地| 91人人澡人人爽人人精品| 国产精品无码专区av在线播放| 8x8x华人在线| xxxxxx在线观看| 日本a级片在线观看| 国产精品h视频| 色姑娘综合天天| 国产91在线亚洲| 国产精品专区在线| 无码播放一区二区三区| 日本一区二区黄色| 免费看黄色一级大片| www.久久91| 8x8x华人在线| 夫妻免费无码v看片| 久久国产色av免费观看| 天天综合网久久| 福利网在线观看| 国产aaa免费视频| 欧美日韩在线视频一区二区三区| 老头吃奶性行交视频| 国产精品久久久久久久av福利| 中文字幕第一页在线视频| 国产一区二区三区在线免费| 黄色动漫在线免费看| 色婷婷.com| 久久99久久久久久| 日本人视频jizz页码69| 青青在线免费视频| 色一情一乱一伦一区二区三区日本| av在线网址导航| 欧美日韩黄色一级片| 中日韩av在线播放| 欧美乱大交xxxxx潮喷l头像| 黄色三级视频在线| 可以在线看黄的网站| 精品久久久久久久无码| 国产青草视频在线观看| 国产九九在线观看| 国产在线精品91| 日本黄色播放器| 亚洲狼人综合干| 毛片在线视频播放| 日韩精品一区二区三区电影| 欧美伦理视频在线观看| 无码 制服 丝袜 国产 另类| 小早川怜子一区二区三区| 国产中文字幕免费观看| 精品国产三级a∨在线| 欧美三级理论片| 日韩精品视频一区二区在线观看| 玖玖精品在线视频| 亚洲网中文字幕| 免费看污污网站| 男女视频网站在线观看| 国产欧美精品aaaaaa片| 手机在线免费毛片| xxww在线观看| 欧美成人黄色网址| 日本888xxxx| 成年人网站大全| 亚洲色欲综合一区二区三区| 草草久久久无码国产专区| 免费一级特黄特色毛片久久看| 特大黑人娇小亚洲女mp4| 伊人网在线免费| 三上悠亚免费在线观看| 国产在线无码精品| 91成人在线视频观看| 日本黄xxxxxxxxx100| 亚洲小说欧美另类激情| 热久久最新地址| 欧美在线观看黄| av在线免费观看国产| 成人免费播放器| 香港三级韩国三级日本三级| 青青草原av在线播放| 91香蕉视频污版| 一本一道久久a久久综合蜜桃| 欧美美女一级片| 日本久久高清视频| 青青草国产精品视频| 精品国产成人av在线免| 天天干天天玩天天操| 男人添女人下部视频免费| 亚洲 自拍 另类小说综合图区| 国产免费观看高清视频| 亚洲xxxx2d动漫1| 国产精品夜夜夜爽张柏芝| 国产中文字幕二区| 超碰影院在线观看| 激情黄色小视频| 国产成人在线小视频| 日韩免费高清在线| 免费成人进口网站| 日韩av资源在线| 亚洲色图欧美自拍| 久久精品国产sm调教网站演员| 国产天堂在线播放| 国产日韩欧美大片| 黄色免费网址大全| 大荫蒂性生交片| www.cao超碰| 亚洲乱码中文字幕久久孕妇黑人| www.色.com| 91国产精品视频在线观看| 无码人妻少妇伦在线电影| www.com黄色片| 国产一区二区网| 97在线免费视频观看| 污污的网站免费| 亚洲欧洲日产国码无码久久99| 又色又爽又黄视频| 性生交免费视频| 免费观看日韩毛片| 日本一级黄视频| 日本一级淫片演员| 图片区乱熟图片区亚洲| 色哟哟精品视频| 日本va中文字幕| 成年人视频观看| 欧美视频在线观看网站| 草草草视频在线观看| 久久精品亚洲天堂| 亚洲第一天堂久久| 亚洲国产精品三区| 天堂在线资源视频| 成人性生交免费看|