美薇 2019-04-19 00:07 采纳率: 100%
浏览 762
已采纳

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条回答 默认 最新

  • threenewbee 2019-04-19 09:46
    关注

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

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog