A String[255]
是一个固定的 256 字节内存块,字符数据直接存储在该内存中。因此,无需序列化即可安全地按原样跨进程边界传递。
A String
另一方面,是动态类型。它只包含一个指向存储在内存中其他位置的字符数据的指针。因此,你不能通过String
按原样跨进程边界,您将传递的只是指针值,这对接收进程没有任何意义。你必须序列化String
数据转换为平面格式,可以安全地传递到接收进程并由接收进程反序列化。例如:
发送方:
type
PDataPipe = ^TDataPipe;
TDataPipe = record
WindowTitleLen: Integer;
WindowTitleData: array[0..0] of Char;
//WindowTitleData: array[0..WindowTitleLen-1] of Char;
end;
var
Wnd: HWND;
s: String;
Data: PDataPipe;
DataLen: Integer;
copyDataStruct : TCopyDataStruct;
begin
Wnd := FindWindow('TForm1', nil);
if Wnd = 0 then Exit;
s := PChar(HookedMessage.lParam);
DataLen := SizeOf(Integer) + (SizeOf(Char) * Length(s));
GetMem(Data, DataLen);
try
Data.WindowTitleLen := Length(s);
StrMove(Data.WindowTitleData, PChar(s), Length(s));
copyDataStruct.dwData := ...; // see notes further below
copyDataStruct.cbData := DataLen;
copyDataStruct.lpData := Data;
SendMessage(Wnd, WM_COPYDATA, 0, LPARAM(@copyDataStruct));
finally
FreeMem(Data);
end;
end;
接收方:
type
PDataPipe = ^TDataPipe;
TDataPipe = record
WindowTitleLen: Integer;
WindowTitleData: array[0..0] of Char;
//WindowTitleData: array[0..WindowTitleLen-1] of Char;
end;
procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var
Data: PDataPipe;
s: string;
begin
Data := PDataPipe(Msg.CopyDataStruct.lpData);
SetString(s, Data.WindowTitleData, Data.WindowTitleLen);
Memo1.Lines.Add(s);
end;
话虽这么说,在任何一种情况下,您确实应该将自己的自定义 ID 号分配给copyDataStruct.dwData
场地。 VCL本身使用WM_COPYDATA
在内部,因此您不想将这些消息与您的消息混淆,反之亦然。您可以使用RegisterWindowMessage()
创建唯一的 ID 以避免与其他使用的 ID 发生冲突WM_COPYDATA
users:
var
dwMyCopyDataID: DWORD;
...
var
...
copyDataStruct : TCopyDataStruct;
begin
...
copyDataStruct.dwData := dwMyCopyDataID;
...
end;
...
initialization
dwMyCopyDataID := RegisterWindowMessage('MyCopyDataID');
var
dwMyCopyDataID: DWORD;
...
procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var
...
begin
if Msg.CopyDataStruct.dwData = dwMyCopyDataID then
begin
...
end else
inherited;
end;
...
initialization
dwMyCopyDataID := RegisterWindowMessage('MyCopyDataID');
最后,WPARAM
的参数WM_COPYDATA
is an HWND
,不是一个HINSTANCE
。如果发件人没有自己的HWND
,只需传递 0。不要传递您的发件人的HInstance
多变的。