我有以下代码作为我控制的一部分。 SetReaderMode函数创建结构并调用此处解释的函数http://msdn.microsoft.com/en-us/library/bb775599(VS.85).aspx
当我运行此代码时,我收到错误
尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
我不确定问题是什么。我做错了什么?
<DllImport("Comctl32.dll", EntryPoint:="#383", _
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Sub DoReaderMode(prmi As READERMODEINFO)
End Sub
<StructLayout(LayoutKind.Sequential)>
Private Structure READERMODEINFO
Dim cbSize As UInt32
Dim hwnd As IntPtr
Dim fFlags As UInt32
Dim prc As IntPtr
Dim pfnScroll As ReaderScrollCallbackDelegate
Dim fFlags2 As TranslateDispatchCallbackDelegate
Dim lParam As IntPtr
End Structure
Private Sub SetReaderMode()
Dim Info As New READERMODEINFO
Info.hwnd = Me.Handle
Info.fFlags = 0
Info.prc = IntPtr.Zero
Info.pfnScroll = New ReaderScrollCallbackDelegate(AddressOf ReaderScrollCallback)
Info.fFlags2 = New TranslateDispatchCallbackDelegate(AddressOf TranslateDispatchCallback)
Info.lParam = IntPtr.Zero
Info.cbSize = Marshal.SizeOf(Info)
DoReaderMode(Info)
End Sub
Private Delegate Function ReaderScrollCallbackDelegate(ByVal prmi As READERMODEINFO, dx As Integer, dy As Integer) As Boolean
Private Delegate Function TranslateDispatchCallbackDelegate(lpmsg As IntPtr) As Boolean
<AllowReversePInvokeCalls()>
Private Function TranslateDispatchCallback(lpmsg As IntPtr) As Boolean
Return True
End Function
<AllowReversePInvokeCalls()>
Private Function ReaderScrollCallback(ByVal prmi As READERMODEINFO, dx As Int32, dy As Int32) As Boolean
Return True
End Function
答案 0 :(得分:1)
不容易破解。假设回签在签名/调用约定方面是正确的,问题可能是由于垃圾收集器在函数SetReaderMode的末尾收集Info,因此回调地址无效。因此,尝试将Info声明为成员变量。如果错误仍然存在,回调签名有问题,但正如我所说,不容易看出错误一目了然。
答案 1 :(得分:1)
我已经弄清楚了。在更仔细地查看文档之后,我在DoReaderMode
定义和ReaderScrollCallback
定义中添加了一个ByRef,因为参数定义为结构的指针,而不仅仅是结构。我还添加了一些其他代码来传递ReaderModeInfo
结构中的矩形。
以下是工作代码。有趣的是,文档声明您单击退出ReaderMode,但是在测试时看起来您必须按住按钮并释放以退出。
<DllImport("Comctl32.dll", EntryPoint:="#383", _
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Sub DoReaderMode(ByRef prmi As READERMODEINFO)
End Sub
<StructLayout(LayoutKind.Sequential)>
Private Structure READERMODEINFO
Dim cbSize As UInt32
Dim hwnd As IntPtr
Dim fFlags As UInt32
Dim prc As IntPtr
Dim pfnScroll As ReaderScrollCallbackDelegate
Dim fFlags2 As TranslateDispatchCallbackDelegate
Dim lParam As IntPtr
End Structure
Private Sub SetReaderMode()
Dim SetReaderModeInfo As READERMODEINFO
Dim rect As New Interop.RECT(Me.Width / 2 - 20, Me.Height / 2 - 20, Me.Width / 2 + 20, Me.Height / 2 + 20)
Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(rect))
Marshal.StructureToPtr(rect, pnt, True)
SetReaderModeInfo = New READERMODEINFO
SetReaderModeInfo.hwnd = Me.Handle
SetReaderModeInfo.fFlags = 1
SetReaderModeInfo.prc = pnt
SetReaderModeInfo.pfnScroll = New ReaderScrollCallbackDelegate(AddressOf ReaderScrollCallback)
SetReaderModeInfo.fFlags2 = New TranslateDispatchCallbackDelegate(AddressOf TranslateDispatchCallback)
SetReaderModeInfo.lParam = IntPtr.Zero
SetReaderModeInfo.cbSize = Marshal.SizeOf(SetReaderModeInfo)
DoReaderMode(SetReaderModeInfo)
Marshal.FreeHGlobal(pnt)
End Sub
Private Delegate Function ReaderScrollCallbackDelegate(ByRef prmi As READERMODEINFO, dx As Integer, dy As Integer) As Boolean
Private Delegate Function TranslateDispatchCallbackDelegate(ByRef lpmsg As Interop.MSG) As Boolean
Private Function TranslateDispatchCallback(ByRef lpmsg As Interop.MSG) As Boolean
Return False
End Function
Private Function ReaderScrollCallback(ByRef prmi As READERMODEINFO, dx As Int32, dy As Int32) As Boolean
Return True
End Function