1

I am developing software on top of a development studio that only uses VBA as a language. (Not one of MS office applications) The studio and service applications are 32bit only, even though they are being executed on a 64bit machine. This environment uses WinWrap Basic 9.1.

I am trying to implement a timer system and so I've turned to Interop code to make it happen. This is the code I've placed in a code module (.bas):

Private Sub timerCallback(ByVal hWnd As Long, ByVal msg As Long, ByVal tmrID As Long, ByVal msDelta As Long)
   '...
End Sub

Private timerID As Long
Private Sub pSetTimer()
    '// set timer to 50ms
    timerID = SetTimer(0, timerID, 50, AddressOf timerCallback)
End Sub
Private Sub pResetTimer()
    If KillTimer(0, timerID) Then timerID = 0
End Sub

Private Delegate Sub TIMERPROC(ByVal hWnd As Long, ByVal msg As Long, ByVal tmrID As Long, ByVal msDelta As Long)
Private Declare Function SetTimer Lib "User32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As TIMERPROC) As Long
Private Declare Function KillTimer Lib "User32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Boolean

It seems to work just fine, returning a unique timerID each time I call pSetTimer. However, the timerCallback never gets called.

Other guides out there that import SetTimer use Long type instead of a delegate. But if I try to do so (or if I try to convert the output of AddressOf timerCallback to a Long or String for the purpose of logging), then it throws the following error:

[10091] ActiveX Automation: no such property or method.

What am I doing wrong?

Edit: I read on WWB's doc that if the sub has no other references it may be deleted rendering the AddressOf invalid. However, I have also tried taking the address of a sub that I know will still be in memory and I get the same error message.

Edit2: I've created a while loop that uses PeekMessage to find the WM_TIMER. And it does get sent. The lParam is supposed to contain the function pointer passed to SetTimer. And it contains a unique 8 digit decimal number, which is the same with multiple calls, but changes whenever the app is restarted. (probable to be a pointer value). However, the callback is still not being called (unless I do so manually.)

The point of what I'm doing is to avoid loop waiting as I don't have access to the top level message loop.

Rhaokiel
  • 813
  • 6
  • 17
  • First thing coming to mind is if it's 32 or 64 bit. API calls are slightly different between them. – Sam Oct 11 '19 at 16:32
  • As far as I can tell all of the code is run as 32bit. In fact, LongLong is not even a recognized keyword in this environment. – Rhaokiel Oct 11 '19 at 16:36

0 Answers0