SendMessage只发送VC ++消息的第一个章程,你能帮忙吗? 只收到第一份包机。
实际上这是我的完整发件人应用代码(VC ++)
// notification->FileName is UCHAR[255]
HWND app = FindWindow(NULL,TEXT("Message Receiver"));
COPYDATASTRUCT cds;
cds.dwData = 0; // can be anything
cds.cbData = sizeof(notification->FileName) - sizeof(UCHAR);
cds.lpData = (void*)notification->FileName;
SendMessageA(app, WM_COPYDATA, (WPARAM)app, (LPARAM)&cds);
我的收件人代码(Delphi)
procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
var
sText: array[0..255] of Char;
s: string;
ms: TMemoryStream;
begin
case Msg.CopyDataStruct.dwData of
0: { Receive Text, Text empfangen}
begin
StrLCopy(sText, Msg.CopyDataStruct.lpData,Min(Length(sText), Msg.CopyDataStruct.cbData));
label1.Caption := sText;
end;
1: { Receive Image, Bild empfangen}
{
begin
ms := TMemoryStream.Create;
try
with Msg.CopyDataStruct^ do
ms.Write(lpdata^, cbdata);
ms.Position := 0;
image1.Picture.Bitmap.LoadFromStream(ms);
finally
ms.Free;
end;
end; }
end;
end;
答案 0 :(得分:1)
您将数据作为8位Ansi发送。但是,如果您使用的是Delphi 2009或更高版本(您没有说),String
和Char
是Unicode,那么您将遇到问题。
将您的Delphi代码更改为以下版本,该代码适用于所有版本:
procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
var
sText: AnsiString;
ms: TMemoryStream;
begin
case Msg.CopyDataStruct.dwData of
0: { Receive Text, Text empfangen}
begin
SetString(sText, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
Label1.Caption := Trim(sText);
end;
1: { Receive Image, Bild empfangen}
{
begin
ms := TMemoryStream.Create;
try
with Msg.CopyDataStruct^ do
ms.Write(lpData^, cbData);
ms.Position := 0;
Image1.Picture.Bitmap.LoadFromStream(ms);
finally
ms.Free;
end;
end;
}
end;
end;
如果您更改C ++代码以发送实际的FileName
长度而不是盲目地发送255,那么您可以从Delphi代码中删除Trim()
。
此代码的另一个问题是0和1是dwData
值的非常差的选择。您应该在双方使用RegisterWindowMessage()
来生成更多唯一值,这些值不太可能与其他人使用WM_COPYDATA
冲突(例如,即使VCL在内部使用WM_COPYDATA
也是如此)。例如:
const UINT MyTextMsg = RegisterWindowMessage(TEXT("MyTextMsg"));
// ...
if (MyTextMsg != 0)
{
COPYDATASTRUCT cds;
cds.dwData = MyTextMsg;
// ...
}
var
MyTextMsg: UINT = 0;
MyImageMsg: UINT = 0;
procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
var
sText: AnsiString;
ms: TMemoryStream;
begin
if (Msg.CopyDataStruct.dwData = MyTextMsg) and (MyTextMsg <> 0) then
begin
// ...
end
else if (Msg.CopyDataStruct.dwData = MyImageMsg) and (MyImageMsg <> 0) then
begin
// ...
end;
end;
initialization
MyTextMsg := RegisterWindowMessage('MyTextMsg');
MyImageMsg := RegisterWindowMessage('MyImageMsg');
此外,只是优化 - 如果您从TCustomMemoryStream
派生一个类而不是TMemoryStream
,您可以将lpData
指针传递给TCustomMemoryStream.SetPointer()
,以便{{1}将能够直接读取消息数据,您不必在内存中单独复制它。
答案 1 :(得分:0)
好像你正在混合unicode和ansi字符串。在第一种情况下不要使用TEXT宏,使用纯ansi字符串。 片段sizeof(TEXT(“消息接收者”)) - sizeof(UCHAR)将计算unicode字符串的无效大小
Unicode字符串TEXT(“消息接收器”)将被读取为“M”,当您将其读取到delphi char数组时,因为unicode中的“M”是两个字符 - “M”和零。