Scott Kilbourn
Scott Kilbourn

Reputation: 1586

SendMessage - Passing a string from VB6 to VB.NET

Good afternoon,

I am attempting to use SendMessage to pass a string from a VB6 EXE, to a .NET 2013 EXE. I know that the message is getting in to the .NET EXE, because I'm able to set a breakpoint on it and it comes up when I call SendMessage from the VB6 EXE. The problem I am having is retrieving the string.

This is how I am attempting to do it:

VB6 Code:

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, Source As Any, ByVal bytes As Long)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal msg As Long, wParam As Long, lParam As Any) As Long

Private Const APPVIEWER_OPEN = &H400

Private Sub Command1_Click()
  Dim hwndAppViewer As Long
  Dim bytBuffer(1 To 255) As Byte
  Dim sParams As String
  Dim lStringAddress As Long

  hwndAppViewer = FindWindow(vbNullString, "DotNetReceiver")

  If hwndAppViewer > 0 Then
    sParams = "STRINGDATA"
    CopyMemory bytBuffer(1), sParams, Len(sParams)
    lStringAddress = VarPtr(bytBuffer(1))
    SendMessage hwndAppViewer, APPVIEWER_OPEN, Me.hwnd, lStringAddress
  End If
End Sub

Here is the .NET code:

Imports System.Runtime.InteropServices

Public Class Form1
  Protected Overrides Sub WndProc(ByRef m As Message)
    Dim sPolicyInformation As String

    If m.Msg = &H400 Then
      sPolicyInformation = Marshal.PtrToStringAnsi(m.LParam)
    Else
      MyBase.WndProc(m)
    End If
  End Sub
End Class

The problem comes when I try and retrieve the string. I am getting a blank string. I noticed that the number in the VB6 lStringAddress and the number in .NET m.lParam are completely different, so I must be missing something about how I'm passing the address through lParam.

Any ideas what I might be missing?

Thank you.

Upvotes: 0

Views: 2484

Answers (1)

user5032396
user5032396

Reputation: 162

You are sending an ANSI string to VB.NET. VB6 was designed for all MS's OSs and 9x wasn't unicode. So all strings passed to API calls will be converted to ANSI. Windows will convert that ANSI string to unicode for the VB.NET program when it recieves it.

Use the sendmessagew function and send the first element of a byte array that's null terminated.

Dim MyStr() as byte
MyStr = "cat" & chrw(0)

The pass only the first element to SendMessageW ie MyStr(0). Windows API uses null terminated C strings. COM and VB6 use BStr (a size header and a non null terminated string).

When passing strings by ref you pass the address of the header. When passing by value you pass the address of the first character (making it a c string if you tack a null on the end).

Upvotes: 1

Related Questions