2015-06-23 85 views
0

下午好,SendMessage函数 - 从VB6将字符串传递到VB.NET

我试图使用SendMessage函数从VB6 EXE传递一个字符串,在.NET 2013 EXE。我知道该消息正在进入.NET EXE,因为我可以在其上设置断点,并且在从VB6 EXE调用SendMessage时它会出现。我遇到的问题是检索字符串。

这是我在尝试做到这一点:

VB6代码:

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 

这里是.NET代码:

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 

问题是当我尝试和检索字符串。我收到一个空白字符串。我注意到,在VB6 lStringAddress和数量在.NET m.lParam数量是完全不同的,所以我必须失去了一些有关如何我路过的地址,通过lParam的。

任何想法我可能会丢失?

谢谢。

+0

要做你想做的事,我相信你需要使用RegisterWindowMessage函数(参见:https://msdn.microsoft.com/en-us/library/windows/desktop/ms644947%28v=vs.85%29 .aspx)来获取可能在应用程序之间传输的消息编号。然后,您将使用PostMessage发送消息给HWND_BROADCAST(&HFFFF)。这两个应用程序都需要使用相同的密钥来调用RegisterWindowMessage以获取要监视的消息编号。 – TnTinMn

+0

而不是使用SendMessage函数洗牌周围的指针的地址空间,您可以考虑使用[WM_COPYDATA(https://msdn.microsoft.com/en-us/library/windows/desktop/ms649011(V = vs.85) .aspx)消息,这更适合这种情况。 –

+1

指针只在其拥有的进程地址空间中有意义。你需要编组数据。 WM_COPYDATA是你的家伙。 –

回答

1

您发送的是ANSI字符串VB.NET。 VB6是为所有MS的操作系统设计的,9x不是unicode。所以传递给API调用的所有字符串都将转换为ANSI。当Windows收到它时,Windows会将该ANSI字符串转换为VB.NET程序的unicode。

使用sendmessagew功能和发送一个字节数组的空值终止的第一个元素。

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

只传递第一个元素SendMessageW即MyStr(0)。 Windows API使用以null结尾的C字符串。 COM和VB6使用BStr(一个大小头和一个非空终止的字符串)。

当传递字符串由参传递标题的地址。当通过值传递时,你传递第一个字符的地址(如果你在最后加上一个空值,把它作为一个c字符串)。