最近接一个任务,要求写一个接口程序,需要要与其他的Win32程序交换信息.
正在使用调用 API 发送 Win32消息的方式实现.
经过几天的查找与实验,与C#程序间的通信已经解决(十分感谢CSDN里的各位大大)但与VB间传递字符串的时候出现问题.
描述如下:C#方,定义要发送的消息的结构为:
/// <summary>
/// 发送WM_COPYDATA消息的数据结构
/// </summary>
internal struct MESSAGE_STRUCT
{
/// <summary>
/// 用户自定义数据
/// </summary>
public int dwData;
/// <summary>
/// 数据长度
/// </summary>
public int cbData;
/// <summary>
/// 数据首地址指针
///</summary>
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}发送语句为:
NativeMethods.SendMessage(this.SoftHandle, NativeMethods.WM_COPYDATA, messageType, ref data);
其中,对方句柄已知(对方能够收到消息),messageType 为自定义的数据,整数101, data是按照上面的定义,每一项都有相应的值:
MESSAGE_STRUCT data = new MESSAGE_STRUCT();
// 自定义整形内容
data.dwData = messageType;
// 传递要发送的数据的长度 + \x00
data.cbData = System.Text.Encoding.Default.GetBytes(message).Length + 1;
// 传递要发送的数据的地址指针
data.lpData = message;现在的问题是在VB侧,无法读出发送过来的内容.我尝试过定义这样的自定义类型:''' 发送WM_COPYDATA消息的数据结构
Type MESSAGE_STRUCT ''' 用户自定义数据
dwData As Long ''' 数据长度
cbData As Long ''' 数据首地址指针
lpData As String * 1000
End Type可是,读取到的前两个数值为0,第三个字符串为乱码.请各位大大救命呀!我已经苦恼好几天了!!!
正在使用调用 API 发送 Win32消息的方式实现.
经过几天的查找与实验,与C#程序间的通信已经解决(十分感谢CSDN里的各位大大)但与VB间传递字符串的时候出现问题.
描述如下:C#方,定义要发送的消息的结构为:
/// <summary>
/// 发送WM_COPYDATA消息的数据结构
/// </summary>
internal struct MESSAGE_STRUCT
{
/// <summary>
/// 用户自定义数据
/// </summary>
public int dwData;
/// <summary>
/// 数据长度
/// </summary>
public int cbData;
/// <summary>
/// 数据首地址指针
///</summary>
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}发送语句为:
NativeMethods.SendMessage(this.SoftHandle, NativeMethods.WM_COPYDATA, messageType, ref data);
其中,对方句柄已知(对方能够收到消息),messageType 为自定义的数据,整数101, data是按照上面的定义,每一项都有相应的值:
MESSAGE_STRUCT data = new MESSAGE_STRUCT();
// 自定义整形内容
data.dwData = messageType;
// 传递要发送的数据的长度 + \x00
data.cbData = System.Text.Encoding.Default.GetBytes(message).Length + 1;
// 传递要发送的数据的地址指针
data.lpData = message;现在的问题是在VB侧,无法读出发送过来的内容.我尝试过定义这样的自定义类型:''' 发送WM_COPYDATA消息的数据结构
Type MESSAGE_STRUCT ''' 用户自定义数据
dwData As Long ''' 数据长度
cbData As Long ''' 数据首地址指针
lpData As String * 1000
End Type可是,读取到的前两个数值为0,第三个字符串为乱码.请各位大大救命呀!我已经苦恼好几天了!!!
虽然多了一个进程,但操作起来非常方便,还可以多个进程捕捉同一个进程的事件和数据。如果感兴趣的话,我再另外回复你。
VB中的String类型(BSTR)与LPSTR根本不是同一类型,你需要改为Long去接收这个指针,然后从指向的区域读出字符串数据
第一步,挂载 WindowProc 方法来处理接收到的消息
pOld = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
这个方法的定义为:
Public Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
所以,lParam 应该接收到的是对方发来的 LParam 这个参数的指针(在其他的消息中已经证实).
第二步,在这个方法中,我定义了一个上述的结构对象:
Dim getStruct As MESSAGE_STRUCT
然后,用
ReadProcessMemory ToHandle, lParam, ByVal VarPtr(getStruct), 1008, stringLeng
的方法,试图复制出发送过来的内容,但是,结果是前两个数字(Long类型)都为0.第三个得到的是一长串'r'. 我Win32下的开发,以及信息的格式和约定等方面,都比较没有经验,请各位达人,不吝赐教! 谢谢,今天会在线等待的.
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)然后,分两次复制出内存的内容:
第一次:
CopyMem getStruct, ByVal lParam, Len(getStruct)
得到结构体内的三个整数.(getStruct 为结构体变量)
''' 发送WM_COPYDATA消息的数据结构
结构体为:
Type MESSAGE_STRUCT
''' 用户自定义数据
dwData As Long
''' 数据长度
cbData As Long
''' 数据首地址指针
lpData As Long
End Type ' (感谢 San_zc_1, 他的意见是对的)
第二次:
CopyMem ByVal StrPtr(getString), ByVal getStruct.lpData, getStruct.cbData
这里复制出字符串的内容.getString 为定义的字符串变量.
在这个位置,需要注意一点:在C#中,传递出来的是Unicdoe的字符串,需要作相应的转换:
getString = StrConv(getString, vbUnicode)
至此,在VB6中,得到C#传递出来的内容.PrevInst 的源码下载页面为:
http://osl.bsw.net.cn/showFiles.php?group_id=15182&release_id=12561
在此,一并向无私开源,为国人的技术提高与进步,做出贡献的所有人,致以敬意!!!
( 有感于最近连环信的铺天盖地, 对默默工作的我们, 赞一个!)