PerformanceCounter/Form1.frm

VERSION 5.00
Begin VB.Form Form1
   Caption         =   "Form1"
   ClientHeight    =   3090
   ClientLeft      =   60
   ClientTop       =   435
   ClientWidth     =   4650
   LinkTopic       =   "Form1"
   ScaleHeight     =   3090
   ScaleWidth      =   4650
   StartUpPosition =   3 'Windows‑Standard
   Begin VB.CommandButton Command1
      Caption         =   "Delay MsgBox by 3000000 µs"
      Height          =   3075
      Left            =   0
      TabIndex        =   0
      Top             =   0
      Width           =   4635
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
'(c)2003, 2004 by Louis. Demonstrates the use of QueryPerformanceCounter in VB. Request by a blackbeltvb
'member. Further information gained from http://www.rookscape.com/vbgaming/tutBL.php.
'
'Downloaded from www.louis‑coder.com.
'Demonstrates how to access modern CPUs' high performance counter feature.
'
'Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long 'oringinal
'Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long'original
'
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long 'VB specific
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long 'VB specific
'
Private Declare Sub STUFF_COPYMEMORY Lib "kernel32.dll" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As AnyByVal cbCopy As Long) 'for debugging
'
Private Type LARGE_INTEGER 'original, debug
    lowpart As Long
    highpart As Long
End Type

Private Sub Command1_Click()
    '
    'DEBUG (shows that VB Currency var can be used instead of the Windows LARGE_INTEGER‑structure)
    Dim c As Currency
    Dim l As LARGE_INTEGER
    '
    l.highpart = 0
    l.lowpart = 2003
    '
    Call STUFF_COPYMEMORY(c, l, 8)
    '
    Debug.Print c 'original number / 1000
    'END Of DEBUG
    '
    Debug.Print "Begun at " + Time$
    Call Delayus(3000000)
    Debug.Print "Finished at " + Time$
    MsgBox "Yeah", vbOKOnly + vbInformation
End Sub

Private Sub Delayus(ByVal Microseconds As Double)
    'on error resume next 'waits for microseconds (note that the Windows scheduler may interrupt the waiting, so the waiting time is not so exact)
    Dim curFreq As Currency
    Dim curStart As Currency
    Dim curEnd As Currency
    Dim dblResult As Double
    Dim dblPassed As Double
    'begin
    QueryPerformanceFrequency curFreq 'get the timer frequency
    QueryPerformanceCounter curStart 'get the start time
    '
    Microseconds = Microseconds / 1000000#
    '
    Do While (dblPassed < Microseconds)
        QueryPerformanceCounter curEnd 'get the end time
        dblPassed = (curEnd ‑ curStart) / curFreq 'calculate the duration (in microseconds)
    Loop
    '
End Sub

'>>>ORIGINAL CODE>>>

'original Pascal (?) code:
'procedure delayus(I : Int64);  Short 100us delay
'
'> > > >Var tic,t,F,s : Int64;
'> > > >begin
'> > > > S:=0;
'> > > > if I<>0 then
'> > > > begin
'> > > >   QueryPerformanceFrequency(F);
'> > > >   QueryPerformanceCounter(tic);
'> > > >   while (S<I) do    {100 usec}
'> > > >   begin
'> > > >     QueryPerformanceCounter(t);
'> > > >     s:=(t‑tic) * 1000000 DIV F ; {F in usec}
'> > > >   end;
'> > > > end;
'> > > >end;

'<<<END OF ORIGINAL CODE<<<

'>>>NEWBIE'S TRY>>>

'NOTE: the following code is an attempt to use the LARGE_INTEGER structure, coded
'before knowing the trick with the VB currency var. The following code does not work.

'Private Sub Delayus(ByVal i As Long)
'    'on error resume next
'    Dim tic As LARGE_INTEGER
'    Dim t As LARGE_INTEGER
'    Dim F As LARGE_INTEGER
'    Dim s As LARGE_INTEGER
'
'    s.highpart = 0
'    s.lowpart = 0
'
'    If (i) Then
'        Call QueryPerformanceFrequency(F)
'        Debug.Print F.highpart
'        Debug.Print F.lowpart
'        Debug.Print LARGE_INTEGER_ToCurrency(F)
'        Call QueryPerformanceCounter(tic)
'        Debug.Print tic.highpart
'        Debug.Print tic.lowpart
'        Debug.Print LARGE_INTEGER_ToCurrency(tic)
'        Do While (s.lowpart < i)
'            Call QueryPerformanceCounter(t)
'            s.lowpart = STUFF_DIV(CurrencyToLong((LARGE_INTEGER_ToCurrency(t) ‑ LARGE_INTEGER_ToCurrency(tic)) * 10000000@), F.lowpart)
'            Debug.Print s.lowpart
'        Loop
'    End If
'
'End Sub
'
'Private Function LARGE_INTEGER_ToCurrency(ByRef LargeIntegerVar As LARGE_INTEGER) As Currency
'    'on error resume next
'    LARGE_INTEGER_ToCurrency = CCur(LargeIntegerVar.highpart) * (2@ ^ 31@ ‑ 1@) + SignedLongToUnsignedCurrency(LargeIntegerVar.lowpart)
'End Function
'
'Private Function SignedLongToUnsignedCurrency(ByVal LongNumber As Long) As Currency
'    'on error resume next
'    If LongNumber < 0 Then
'        SignedLongToUnsignedCurrency = 2147483648@ + CCur(LongNumber And 2147483647)
'    Else
'        SignedLongToUnsignedCurrency = CCur(LongNumber)
'    End If
'End Function
'
'Private Function CurrencyToLong(ByVal CurrencyNumber As Currency) As Long
'    'on error resume next
'    If CurrencyNumber > 2147483647@ Then
'        CurrencyToLong = 2147483647
'    Else
'        CurrencyToLong = CLng(CurrencyNumber)
'    End If
'End Function
'
'Private Function STUFF_DIV(ByVal Value As LongByVal Divisor As Long) As Long
'    'on error resume next 'how often one number 'goes into' an other
'    STUFF_DIV = (Value ‑ (Value Mod Divisor)) \ Divisor
'End Function

'<<<END OF NEWBIE'S TRY<<<


[END OF FILE]