我得到以下错误,并且不知道如何解决这个问题: BC30581:Adressoff Expression无法转换为Long,因为Long不是委托类型。
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 TimerID As Long
Public TimerSeconds As Single
Sub StartTimer()
TimerSeconds = 1000 ' how often to "pop" the timer.
TimerID = SetTimer(0&, 0&, TimerSeconds * 1000&, AddressOf TimerProc)
End Sub
Sub EndTimer()
On Error Resume Next
KillTimer(0&, TimerID)
End Sub
Sub TimerProc(ByVal HWnd As Long, ByVal uMsg As Long,
ByVal nIDEvent As Long, ByVal dwTimer As Long)
MsgBox("test123")
End Sub
答案 0 :(得分:0)
您的PInvoke signature似乎错了。试试这个:
Public Delegate Sub TimerProc(ByVal hWnd As IntPtr, ByVal uMsg As UInteger, ByVal nIDEvent As IntPtr, ByVal dwTime As UInteger)
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function SetTimer(ByVal hWnd As IntPtr, ByVal nIDEvent As IntPtr, ByVal uElapse As UInteger, ByVal lpTimerFunc As TimerProc) As IntPtr
End Function
您还需要更改KillTimer
的pinvoke签名。有关更多信息,请参见pinvoke.net。
答案 1 :(得分:0)
我得到了它的工作:
Imports System.Runtime.InteropServices
Public Class TimerMethods
<DllImport("user32.dll", SetLastError:=True)>
Public Shared Function SetTimer(ByVal hWnd As IntPtr, ByVal nIDEvent As IntPtr, ByVal uElapse As UInteger, ByVal lpTimerFunc As TimerProc) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)>
Public Shared Function KillTimer(ByVal hWnd As IntPtr, ByVal nIDEvent As IntPtr) As Boolean
End Function
Public Delegate Sub TimerProc(ByVal hWnd As IntPtr, ByVal uMsg As UInteger, ByVal nIDEvent As IntPtr, ByVal dwTime As UInteger)
Public timerID As IntPtr
Sub StartTimer(windowHandle As IntPtr)
Dim timerSeconds = 3 ' how often to "pop" the timer.
timerID = SetTimer(windowHandle, IntPtr.Zero, CUInt(timerSeconds * 1000), AddressOf TimerMethods.TimerCallback)
If timerID = IntPtr.Zero Then
Debug.WriteLine("Timer start error.")
Else
Debug.WriteLine("Timer started.")
End If
End Sub
Sub EndTimer()
KillTimer(IntPtr.Zero, timerID)
End Sub
Public Shared Sub TimerCallback(ByVal hWnd As IntPtr, ByVal uMsg As UInteger, ByVal nIDEvent As IntPtr, ByVal dwTime As UInteger)
MsgBox(uMsg)
End Sub
End Class
和一个简单的表单,只需一个按钮即可启动计时器:
Public Class Form1
Dim t As TimerMethods
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
t = New TimerMethods
t.StartTimer(Me.Handle)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
If t IsNot Nothing Then
t.EndTimer()
End If
End Sub
End Class
您不必使用windowHandle
将计时器绑定到表单:您可以使用IntPtr.Zero
代替。
每次看到像hWnd
这样的变量名称时,它都需要一个句柄,这是VB.NET中的IntPtr
。
答案 2 :(得分:0)
使用PInvoke执行此操作似乎没什么意义。您可以轻松使用Windows窗体计时器:
Public Class Form3
Private _timer As Timer
Public Sub StartTimer()
_timer = New Timer()
_timer.Interval = 1000 ' timer interval in ms
AddHandler _timer.Tick, AddressOf TimerProc
_timer.Enabled = True
End Sub
Public Sub EndTimer()
_timer.Enabled = False
RemoveHandler _timer.Tick, AddressOf TimerProc
End Sub
Sub TimerProc(sender As Object, e As EventArgs)
MsgBox("test123")
End Sub
End Class
答案 3 :(得分:-1)
我已经在Excel 2013中测试了VBE中的代码并成功运行。
答案 4 :(得分:-1)
我事先声明此解决方案适用于VBA
环境
因为那是我写的那个阶段可能的那个
我让它运行了一些编辑:
在_
和SetTimer()
函数声明
KillTimer ()
”
EndTimer()
已将KillTimer
分配给Long
变量,我也声明了
TimerProc()
中的添加了对EndTimer()的调用以阻止它!!!
下面是我的工作代码:
Option Explicit
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 TimerID As Long
Public TimerSeconds As Single
Sub StartTimer()
TimerSeconds = 1000 ' how often to "pop" the timer.
TimerID = SetTimer(0&, 0&, TimerSeconds * 1000&, AddressOf TimerProc)
End Sub
Sub EndTimer()
Dim i As Long '<--| added
On Error Resume Next
i = KillTimer(0&, TimerID) '<--| added
End Sub
Sub TimerProc(ByVal HWnd As Long, ByVal uMsg As Long, _
ByVal nIDEvent As Long, ByVal dwTimer As Long)
MsgBox ("test123")
EndTimer '<--| added !!!
End Sub