Question

At work we have a lot of legacy VB6 code. I am implementing custom messaging between the old VB6 code and a new VB.NET project. I would like to send the name property of a VB6 control and the name length via the SendMessage api call in VB6 and assemble the string in the .NET project.

The code in VB6 looks like this:

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

So I'm sending a custom windows message WM_CONTROLNAME to the hwnd of the .NET form, with a wParam StrPtr of the string and a lParam with the length of the string.

In the .NET project I have a message handler that calls a function GetText to reassemble the string from the pointer and string length passed in the message params:

    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

This all works properly up to the point that GetText is supposed to return the original string. I've tried to fill a StringBuilder with the GetWindowText API call using the StrPtr and and length to no success. I've also tried CopyMemory but that doesn't seem to be correct either. What is the best way to take this pointer and string length and turn it into a string in my GetText method? Thanks in advance.

EDIT: This is the code in the the .NET wndProc override that successfully gets my string. Per the answerer's suggestion I used WM_COPYDATA. After passing the structure by reference in SendMessage from VB6, I marshal it back to the structure in .NET. The string pointer in the structure is now valid in VB.NET and I marshal it back to a string.

    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
Was it helpful?

Solution

You must remember that the address of a pointer is relative to a specific process. So, the pointer you send (which just becomes an integer) means nothing to the receiving process (it'll just be a random address to unrelated memory).

You should use WM_COPYDATA instead:

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top