1

コントロールの一部として次のコードがあります。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
4

2 に答える 2

1

割れやすいナットではありません。コールバックが署名/呼び出し規約に関して正しいと仮定すると、問題は、カーベッジコレクターが関数SetReaderModeの最後に情報を収集するため、コールバックアドレスが無効になることです。したがって、Infoをメンバー変数として宣言してみてください。エラーが残っている場合、コールバック署名に何か問題がありますが、私が言ったように、エラーを一目で確認するのはそれほど簡単ではありません。

于 2011-06-07T18:48:40.580 に答える
1

私はそれを理解しました。ドキュメントをさらに詳しく確認した後、引数が構造体だけでなく構造体へのポインタとして定義されているため、DoReaderMode定義と定義にByRefを追加しました。また、構造ReaderScrollCallback内の長方形を渡すために他のコードを追加しました。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
于 2011-06-08T13:15:58.777 に答える