问题描述
我有以下代码作为我的控件的一部分.SetReaderMode 函数创建结构并调用此处解释的函数,http://msdn.microsoft.com/en-us/library/bb775599(VS.85).aspx
I have the following code as part of my control. SetReaderMode function creates the structure and calls the function explained here, http://msdn.microsoft.com/en-us/library/bb775599(VS.85).aspx
当我运行此代码时,出现错误
When I run this code, i get the error
试图读取或写入受保护的内存.这通常表明其他内存已损坏.
我不确定可能是什么问题.我做错了什么?
I'm not sure what the issue may be. What am I doing wrong?
<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
推荐答案
我已经想通了.在更仔细地查看文档后,我在 DoReaderMode
定义和 ReaderScrollCallback
定义中添加了一个 ByRef,因为参数被定义为指向结构的指针,而不仅仅是结构.我还添加了一些其他代码来在 ReaderModeInfo
结构中传递矩形.
I've figured it out. After reviewing the documentation more closely, I've added a ByRef to the DoReaderMode
definition and to the ReaderScrollCallback
definition, since the arguments where defined as pointers to structures, not just structures. I also added some other code to pass the rectangle in the ReaderModeInfo
structure.
以下是工作代码.有趣的是,文档指出您单击以退出 ReaderMode,但是在测试时,您似乎必须按住按钮然后松开才能退出.
Below is the working code. Interestingly, the documentation states that you click to exit ReaderMode, however when testing it looks like you have to hold the button down and release to exit.
<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
这篇关于错误调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!