職場では、多くのレガシー 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