0

職場では、多くのレガシー VB6 コードがあります。古い VB6 コードと新しい VB.NET プロジェクトの間でカスタム メッセージングを実装しています。VB6 コントロールの name プロパティと名前の長さを VB6 の SendMessage API 呼び出しを介して送信し、.NET プロジェクトで文字列を組み立てたいと思います。

VB6 のコードは次のようになります。

    SendMessage hwnd, WM_CONTROLNAME, StrPtr(sControlName), CLng(Len(sControlName))

そこで、文字列の wParam StrPtr と文字列の長さの lParam を使用して、カスタム Windows メッセージ WM_CONTROLNAME を .NET フォームの hwnd に送信しています。

.NET プロジェクトには、関数 GetText を呼び出して、メッセージ パラメーターで渡されたポインターと文字列の長さから文字列を再構築するメッセージ ハンドラーがあります。

    Protected OverRides Sub WndProc(ByRef m as message)
      If m.msg = WM_CONTROLNAME Then
        p_sControlName = GetText(m.wParam, m.lParam)
      Else
        Mybase.WndProc(m)
      End If
    End Sub

これはすべて、GetText が元の文字列を返すことになっている時点まで適切に機能します。StrPtr と長さを使用して GetWindowText API 呼び出しで StringBuilder を埋めようとしましたが、成功しませんでした。CopyMemory も試しましたが、それも正しくないようです。このポインターと文字列の長さを取得して、GetText メソッドで文字列に変換する最良の方法は何ですか? 前もって感謝します。

編集:これは、文字列を正常に取得する .NET wndProc オーバーライドのコードです。回答者の提案に従って、WM_COPYDATA を使用しました。VB6 から SendMessage で構造体を参照渡しした後、.NET の構造体にマーシャリングします。構造体の文字列ポインターが VB.NET で有効になり、マーシャリングして文字列に戻します。

    If m.Msg = WM_COPYDATA Then
      Dim StringInfo As cds = New cds
      Dim sControlName As String = String.Empty
      StringInfo = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(cds)), cds)
      sControlName = Marshal.PtrToStringAnsi(StringInfo.lpData, StringInfo.cbData)
    End If
4

1 に答える 1

2

ポインタのアドレスは特定のプロセスに関連していることを覚えておく必要があります。したがって、送信するポインター (整数になるだけ) は、受信プロセスにとっては何の意味もありません (関係のないメモリへのランダムなアドレスになるだけです)。

WM_COPYDATA代わりに次を使用する必要があります。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms649011%28v=vs.85%29.aspx

于 2013-09-14T06:52:47.410 に答える