XBa*_*000 3 delphi process sendmessage windows-messages
我用来发送两个独立进程的数据,但它失败了.它只在相同的过程下工作......这是概念.
// ------------------------------------------------ -----------------------------------
MainApps
// ------------ -------------------------------------------------- ---------------------
Type
PMyrec = ^TMyrec;
TMyrec = Record
name : string;
add : string;
age : integer;
end;
:OnButtonSend
var aData : PMyrec;
begin
new(aData);
aData.Name := 'MyName';
aData.Add := 'My Address';
aData.Age : 18;
SendMessage(FindWindow('SubApps'),WM_MyMessage,0,Integer(@aData));
end;
Run Code Online (Sandbox Code Playgroud)
// ------------------------------------------------ -----------------------------------
SubApps
// ------------ -------------------------------------------------- ---------------------
Type
PMyrec = ^TMyrec;
TMyrec = Record
name : string;
add : string;
age : integer;
end;
Run Code Online (Sandbox Code Playgroud)
:OnCaptureMessage
var
aData : PMyrec;
begin
aData := PMyrec(Msg.LParam);
showmessage(aData^.Name);
end;
Run Code Online (Sandbox Code Playgroud)
Rob*_*edy 14
你是对的.地址仅在单个进程中具有意义.您在第一个进程中创建的PMyRec值只是目标进程中的垃圾地址.
要通过窗口消息将任意内存块发送到另一个进程,您应该使用该wm_CopyData消息.您将该消息提供给数据的地址和大小,操作系统负责将其复制到目标进程的地址空间中.
由于您的数据包含一个字符串,在内部表示为另一个指针,因此仅复制记录的12个字节是不够的.您需要分配额外的内存来将记录和字符串数据保存在单个内存块中,以便wm_CopyData可以复制它,目标进程可以读取它.
这是一种方法,使用流将数据收集到单个内存块中.
procedure SendRecord(Source, Target: HWnd; const Rec: TMyRec);
var
Buffer: TMemoryStream;
Len: Integer;
CopyData: TCopyDataStruct;
begin
Buffer := TMemoryStream.Create;
try
Len := Length(Rec.name);
Buffer.Write(Len, SizeOf(Len));
if Len > 0 then
Buffer.Write(Rec.name[1], Len * SizeOf(Char));
Len := Length(Rec.add);
Buffer.Write(Len, SizeOf(Len));
if Len > 0 then
Buffer.Write(Rec.add[1], Len * SizeOf(Char));
Buffer.Write(Rec.age, SizeOf(Rec.age));
CopyData.dwData := 0;
CopyData.cbData := Buffer.Size;
CopyData.lpData := Buffer.Memory;
SendMessage(Target, wm_CopyData, Source, LParam(@CopyData));
finally
Buffer.free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
除了字符串的字符外,我们还会编写字符串的长度,以便收件人知道每个字符所属的字符数.收件人的代码如下所示:
procedure TBasicForm.WMCopyData(var Message: TWMCopyData);
var
Rec: TMyRec;
Len: Integer;
Buffer: TStream;
begin
Buffer := TReadOnlyMemoryStream.Create(
Message.CopyDataStruct.lpData, Message.CopyDataStruct.cbData);
try
if Message.CopyDataStruct.dwData = 0 then begin
Buffer.Read(Len, SizeOf(Len));
SetLength(Rec.name, Len);
if Len > 0 then
Buffer.Read(Rec.name[1], Len * SizeOf(Char));
Buffer.Read(Len, SizeOf(Len));
SetLength(Rec.add, Len);
if Len > 0 then
Buffer.Read(Rec.add[1], Len * SizeOf(Len));
Buffer.Read(Rec.age, SizeOf(Rec.age));
// TODO: Do stuff with Rec here.
Message.Result := 1;
end else
inherited;
finally
Buffer.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
我使用了非标准,TReadOnlyMemoryStream因为它使一切变得更容易.这是一个简单的实现:
type
TReadOnlyMemoryStream = class(TCustomMemoryStream)
public
constructor Create(Mem: Pointer; Size: LongInt);
function Write(const Buffer; Count: LongInt): LongInt; override;
end;
constructor TReadOnlyMemoryStream.Create;
begin
inherited Create;
SetPointer(Mem, Size);
end;
function TReadOnlyMemoryStream.Write;
begin
Result := 0;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5889 次 |
| 最近记录: |