表达式无法转换为长错误

时间:2016-07-25 08:37:15

标签: vb.net

我得到以下错误,并且不知道如何解决这个问题: 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

5 个答案:

答案 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

参考:pinvoke.net/default.aspx/user32.SetTimer

答案 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