首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在VBA中使用可等待计时器对象-无效句柄错误

在VBA中使用可等待计时器对象-无效句柄错误
EN

Stack Overflow用户
提问于 2019-06-09 22:21:35
回答 1查看 92关注 0票数 0

我尝试在VBA中使用可等待的定时器对象,因为我想异步调用延迟不到1秒的东西(所以没有Application.OnTime),并且有参数(所以没有SetTimer API)。

我还没有发现有人在其他地方尝试这样做,所以我不得不从头开始做,但我认为这应该是可行的。以下是API声明:

代码语言:javascript
复制
Public Declare Function CreateWaitableTimer Lib "kernel32" Alias "CreateWaitableTimerA" ( _
                        ByVal lpTimerAttributes As Long, _
                        ByVal manualReset As Boolean, _
                        ByVal lpTimerName As Long) As Long
'The A meaning Ansi not Unicode https://jeffpar.github.io/kbarchive/kb/145/Q145727/

Public Declare Function SetWaitableTimer Lib "kernel32" ( _
                        timerHandle As Long, _
                        lpDueTime As fileTime, _
                        lPeriod As Long, _
                        pfnCompletionRoutine As Long, _
                        lpArgToCompletionRoutine As Long, _
                        fResume As Boolean) As Boolean

它引用了一个结构( fileTime )

代码语言:javascript
复制
'see https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a28a32c6-df4e-41b9-94ce-6260812dd92f/problem-trying-to-run-32-bit-vba-program-on-a-64-bit-machine?forum=exceldev
Public Type fileTime
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

我是这样调用的:

代码语言:javascript
复制
'[...]

args = 1234 'public args As Long so it doesn't go out of scope while the timer is waiting

Dim timerHandle As Long
timerHandle = CreateWaitableTimer(0, False, 0)

Debug.Print GetSystemErrorMessageText(Err.LastDllError)

If Not SetWaitableTimer(timerHandle, absoluteDueTime, 0, AddressOf TimerCallbacks.pointerProc, VarPtr(args), False) Then
    Debug.Print "Error: "; GetSystemErrorMessageText(Err.LastDllError)
End If

GetSystemErrorMessageText来自奇普·皮尔逊。absoluteDueTime是一个fileTime变量,在该过程的前面设置为Now +1秒。我要进入即时窗口:

0-操作已成功完成。

错误:6-句柄无效。

这意味着CreateWaitableTimer似乎可以工作,但SetWaitableTimer不能。

FWIW TimerCallbacks.pointerProc看起来像这样:

代码语言:javascript
复制
Public Sub pointerProc(ByVal argPtr As Long, ByVal timerLowValue As Long, ByVal timerHighValue As Long)
    Debug.Print "pointerProc called"; Time
End Sub

(但我不认为这就是错误所在…)

EN

回答 1

Stack Overflow用户

发布于 2019-06-09 22:35:37

哦,问题在于所有东西的隐式byRef:

代码语言:javascript
复制
Public Declare Function SetWaitableTimer Lib "kernel32" ( _
                        timerHandle As Long, _
                        lpDueTime As fileTime, _
                        lPeriod As Long, _
                        pfnCompletionRoutine As Long, _
                        lpArgToCompletionRoutine As Long, _
                        fResume As Boolean) As Boolean

必须将指针传递给byVal,否则它们会立即被延迟吗?这是正确的吗:

代码语言:javascript
复制
Public Declare Function SetWaitableTimer Lib "kernel32" ( _
                        byVal timerHandle As Long, _
                        byRef lpDueTime As fileTime, _
                        byRef lPeriod As Long, _
                        byVal pfnCompletionRoutine As Long, _
                        byVal lpArgToCompletionRoutine As Long, _
                        byRef fResume As Boolean) As Boolean

不确定是否需要所有的byRef

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56515365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档