2017-06-07 30 views
0
Dim fl_prevproc As SubClassProcDelegate 

我已经创建了如下功能:WindowProc函数的使用完全相同的参数为委托功能当调用委托库API遇到错误InValidFunctionPointerInDelegate检测

Private Function WindowProc(ByVal hw As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer 

    Dim i As Integer 

    If uMsg = VB_WM_USER_PLUS_1 Then 

     CheckForResponses() 
    Else 
     For i = 0 To FORMLIST_END 
      If hw = Formlist(i).fl_gHW Then 
       WindowProc = CallWindowProc(Formlist(i).fl_prevproc, hw, uMsg, wParam, lParam) 
      End If 
     Next i 
    End If 
End Function 

宣言

Public Function SetupClassNotification() As Boolean 
    Dim subclassform As System.Windows.Forms.Form 
    Dim i As Integer 
     For i = 0 To FORMLIST_END 
     If Formlist(i).fl_threadid = 0 Then 
     subclassform = New frmSubclassingForm 
     subclassform.Hide() 
     Formlist(i).fl_prevproc = SetWindowLong(subclassform.Handle.ToInt32, GWL_WNDPROC, AddressOf WindowProc) 
     Exit Function 
     End If 
     Next i 
End Function 

实施Lib API如下:

Delegate Function SubClassProcDelegate(ByVal hw As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer 

Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As SubClassProcDelegate, ByVal hwnd As Integer, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer 

Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal attr As Integer, ByVal lVal As SubClassProcDelegate) As SubClassProcDelegate 

执行停止在一个行:

Formlist(i).fl_prevproc = SetWindowLong(subclassform.Handle.ToInt32, GWL_WNDPROC, AddressOf WindowProc) 

我得到的错误消息是0xffff0a95通入运行时是 转换为代表

无效函数指针。传递无效函数指针为 转换为委托可能导致崩溃,损坏或数据丢失。

任何帮助将不胜感激。谢谢。

回答

1

声明窗口句柄为Integer问题尤其是如果您使用的是64位操作系统;使用IntPtrSafeHandlewParamlParam也应该是IntPtr。

这就是说,为什么不使用.net NativeWindow Class挂钩到窗口过程?

编辑:

下面是使用Win32 API的工作示例。我仍然建议您实施基于NativeWindow类的解决方案。

Imports System.Runtime.InteropServices 

Public Class Form1 
    Private prevWndProc As IntPtr 
    Public Delegate Function WndProcDelegate(ByVal hWnd As IntPtr, ByVal msg As UInt32, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr 

    <System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetWindowLong")> _ 
    Private Shared Function SetWindowLong32(ByVal hWnd As IntPtr, nIndex As Int32, ByVal dwNewLong As IntPtr) As IntPtr 
    End Function 

    <System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetWindowLongPtr")> _ 
    Private Shared Function SetWindowLongPtr64(ByVal hWnd As IntPtr, nIndex As Int32, ByVal dwNewLong As IntPtr) As IntPtr 
    End Function 

    Private Shared Function SetWindowProc(hwnd As IntPtr, wndProcDelegate As WndProcDelegate) As IntPtr 
     Const GWL_WNDPROC As Int32 = -4 

     Dim ptr As IntPtr = Marshal.GetFunctionPointerForDelegate(wndProcDelegate) 
     If IntPtr.Size = 8 Then 
      Return SetWindowLongPtr64(hwnd, GWL_WNDPROC, ptr) 
     Else 
      Return SetWindowLong32(hwnd, GWL_WNDPROC, ptr) 
     End If 
    End Function 

    <DllImport("user32.dll")> _ 
    Private Shared Function CallWindowProc(lpPrevWndFunc As IntPtr, hWnd As IntPtr, Msg As UInt32, wParam As IntPtr, lParam As IntPtr) As IntPtr 
    End Function 

    Protected Overrides Sub OnLoad(e As EventArgs) 
     MyBase.OnLoad(e) 
     prevWndProc = SetWindowProc(Me.Handle, AddressOf MyWindowProcedure) 
    End Sub 

    Private Function MyWindowProcedure(ByVal hWnd As IntPtr, ByVal msg As UInt32, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr 
     Debug.Print(msg.ToString) 
     Return CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam) 
    End Function 
End Class 
+0

尝试与IntPtr以及。没有工作。该代码位于Module中。我仍然可以使用.Net NativeWindow类吗? –

+0

@ H.P。,我添加了一个使用API​​函数的例子。我仍然建议您尝试实现基于NativeWindow的解决方案,如该类的示例中所示。 – TnTinMn