如何从传统的StrPtr中获取.NET中的字符串

时间:2013-09-14 03:32:00

标签: .net vb.net winapi vb6 unmanaged

在工作中我们有很多遗留的VB6代码。我正在实现旧的VB6代码和新的VB.NET项目之间的自定义消息传递。我想通过VB6中的SendMessage api调用发送VB6控件的name属性和名称长度,并在.NET项目中汇编字符串。

VB6中的代码如下所示:

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

所以我将一个自定义的Windows消息WM_CONTROLNAME发送到.NET表单的hwnd,字符串的wParam StrPtr和字符串长度的lParam。

在.NET项目中,我有一个消息处理程序,它调用一个函数Ge​​tText来重新组装指针中的字符串和消息参数中传递的字符串长度:

    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

1 个答案:

答案 0 :(得分:2)

您必须记住指针的地址是相对于特定进程的。所以,你发送的指针(它只是一个整数)对接收进程没有任何意义(它只是一个随机地址到无关内存)。

您应该使用WM_COPYDATA代替:

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