0

I have declared SetTimer in my VB code (under Windows 10 64-bit and Excel 64-bit) as follows:

#If Win64 Then                              ' 64-bit Windows
                                            ' ---------------
  #If VBA7 Then                             ' 64-bit Excel:
                                            ' -------------

    Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, _
                                                           ByVal nIDEvent As LongPtr, _
                                                           ByVal uElapse As Long, _
                                                           ByVal lpTimerFunc As LongPtr) As LongPtr
    Public settimer_result As LongPtr       ' Result value of SetTimer.
    Public Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, _
                                                            ByVal nIDEvent As LongPtr) As Long
    Public killtimer_result As Long         ' Result value of KillTimer.

...
    Public Const timer_interval As Long = 1000    
...

It works fine, when I run the program, but as soon as I set a break point to debug, Excel crashes at this statement:

settimer_result = SetTimer(0&, 0&, timer_interval, AddressOf TimerProc)

I have also tried with LongLong instead of LongPtr, but it still crashes.

Would really appreciate any help on this.

GSerg
  • 76,472
  • 17
  • 159
  • 346
peranders
  • 1
  • 1
  • Doesn't 0& just declare as a literal `Long` but then it immediately gets converted to `LongLong` on 64 bit Excel because of your `LongPtr` declaration? I would do away with the `&` symbols, they're meant for ensuring the correct type of data (Long not Integer) is passed to weakly typed declarations, but yours are strongly typed so you don't need them. Although I'd be surprised if this is what's causing the crash. – Greedo Sep 11 '19 at 08:55
  • HI Greedo, Thanks for the suggestion. I tried it, but it still crashes. Any other suggestion? Best regards, Per-Anders – peranders Sep 16 '19 at 17:26

1 Answers1

2

You seem to misunderstand the meaning of the conditional compilation constants.

Win64 is not "64-bit Windows", it tells you the bitness of the Office.

VBA7 is not "64-bit Office", it tells you whether the Office is new enough to support the LongPtr type and the PtrSafe keyword, regardless of the bitness.

Thus, the correct declaration would be

#If VBA7 Then

Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, _
                                                       ByVal nIDEvent As LongPtr, _
                                                       ByVal uElapse As Long, _
                                                       ByVal lpTimerFunc As LongPtr) As LongPtr

Public Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, _
                                                        ByVal nIDEvent As LongPtr) As Long

Public settimer_result As LongPtr       ' Result value of SetTimer.

#Else

Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, _
                                               ByVal nIDEvent As Long, _
                                               ByVal uElapse As Long, _
                                               ByVal lpTimerFunc As Long) As Long

Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, _
                                                ByVal nIDEvent As Long) As Long

Public settimer_result As Long       ' Result value of SetTimer.

#End If

Public killtimer_result As Long         ' Result value of KillTimer.

Note that you do not need to use #If Win64.

If your TimerProc sub has correct arguments (LongPtr, Long, LongPtr, Long), then it might very well be that the IDE is unable to keep receiving the timer callbacks while a break point is set, so it crashes.

GSerg
  • 76,472
  • 17
  • 159
  • 346
  • Thanks for your answer GSerg, but it stills crashes even though I use your declarations. I got this combination of conditional combination constants from this answer: https://stackoverflow.com/questions/20269844/api-timers-in-vba-how-to-make-safe Any other idea what I could do? – peranders Sep 09 '19 at 15:03
  • I think it's not a matter of declaration, but a matter of the sensitive character of Timer API. For example, 1. If the TimerProc sub has an error, the Office app crashes. 2. If the TimerProc sub calls itself recursively, the Office app crashes. 3. If the Timer that had been started is not killed after closing the document, the Office app will crash some time later. Like the above cases, if the routine is interfered by something like a breakpoint, I think, the app will crash there. – konahn Nov 23 '20 at 07:42