Glad you like it...
Unfortunately, getting it to work in 97 is going to be a challenge since the AddressOf operator is unsupported.
It's tempting to use Application.OnTime or other easily accessible VBA time related stuff but I'm not sure there's a way of using any of these with fractions of a second (which we need for animating)
I think the best option is write your own equivalent function for AddressOf by using the older VBA Win API functions. This won't run in Office2000+ so if we use the conditional compilation directive we can have one command for 97 and another for 2000+.
So, in your form code:
1. Add the required function declarations
Private Declare Function GetCurrentVbaProject Lib "vba332.dll" _
Alias "EbGetExecutingProj" (hProject As Long) As Long
Private Declare Function GetFuncID Lib "vba332.dll" Alias _
"TipGetFunctionId" (ByVal hProject As Long, ByVal strFunctionName As String, _
ByRef strFunctionId As String) As Long
Private Declare Function GetAddr Lib "vba332.dll" Alias _
"TipGetLpfnOfFunctionId" (ByVal hProject As Long, ByVal strFunctionId As String, _
ByRef lpfn As Long) As Long
2. Add this new function to be used in 97
Private Function AddrOf(strFuncName As String) As Long
' Returns a function pointer of a VBA public function given its name. This function
' gives similar functionality to the VBA6 AddressOf param type.
Dim hProject As Long
Dim lngResult As Long
Dim strID As String
Dim lpfn As Long
Dim strFuncNameUnicode As String
Const NO_ERROR = 0
' The function name must be in Unicode, so convert it.
strFuncNameUnicode = StrConv(strFuncName, vbUnicode)
' Get the current VBA project
Call GetCurrentVbaProject(hProject)
' Make sure we got a project handle
If hProject <> 0 Then
' Get the VBA function ID (whatever that is!)
lngResult = GetFuncID(hProject, strFuncNameUnicode, strID)
' We have to check this because we GPF if we try to get a function pointer
' of a non-existent function.
If lngResult = NO_ERROR Then
' Get the function pointer.
lngResult = GetAddr(hProject, strID, lpfn)
If lngResult = NO_ERROR Then
AddrOf = lpfn
End If
End If
End If
End Function
3. Change the StartTimer routine to conditionally compile the correct statement for the version of VBA being used[VBA]Sub StartTimer()
TimerSeconds = 250 'timer interval (in milliseconds)
#If VBA6 Then 'compiled in only Excel 2000 and the later version
TimerID = SetTimer(0&, 0&, TimerSeconds, AddressOf TimerProc)
#Else 'compiled in Excel 97
TimerID = SetTimer(0&, 0&, TimerSeconds, AddrOf("TimerProc"))
#End If
End Sub
That should do it... it seems to work fine for me but I would recommend some extensive testing (both versions) to be sure you trap any errors - particularly unexpected return values from the API functions since they can be somewhat unpredictable.
Enjoy...