美薇 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 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题