vb.net Invoke”类型的已垃圾回收委托进行了回调。

一个签名版的二次开发,遇到下面问题

WindowsApplication1.Module1+SubClassProcDelegate::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Module1.SubclassWindow(Me.Handle)
    End Sub

Module Module1

Public Const HD_OK As Integer = 31111
Public Const HD_CANCEL As Integer = 31112
Public Const HD_REALTIMEDATA As Integer = 31113
Public inkingWindowWidth As Integer
Public inkingWindowHeight As Integer
Private Const GWL_WNDPROC = (-4)
Private procOld As Integer

Private Declare Function CallWindowProc Lib "USER32.DLL" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Integer, ByVal hWnd As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As SubClassProcDelegate) As Integer '重载API函数,最后一个参数为委托类型,注意Long类型参数变成了Integer.

Delegate Function SubClassProcDelegate(ByVal hwnd As Integer, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer '定义窗口过程的委托类型

Public Sub SubclassWindow(ByVal hWnd As Integer)
    procOld = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf SubWndProc)
End Sub


Public Function SubWndProc(ByVal hWnd As Integer, ByVal iMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    If hWnd = Form1.Handle.ToInt32 Then
        Dim X, Y, Pressure, IsPenDown As Integer
        X = wParam And 65535
        Y = (wParam / 65536) And 65535

        X = (X / 65535 * inkingWindowWidth) And 65535
        Y = (Y / 65535 * inkingWindowHeight) And 65535

        Pressure = lParam And 65535
        IsPenDown = (lParam / 65536) And 65535

        SubWndProc = True
        Exit Function
    End If
    SubWndProc = CallWindowProc(procOld, hWnd, iMsg, wParam, lParam)
End Function

End Module

1个回答

首先,VB.NET里有原生的挂钩消息和子类化的办法,比如说直接重写窗体的 WndProc 方法,不用API函数,那样更安全。

你的代码本身似乎没有什么问题,但是要在窗体关闭的时候用SetWindowLong再把原来的窗口函数恢复回去,否则会崩溃。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐