2017-06-07 31 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