所以,我有一个类使用 WM_COPYDATA 来允许应用程序进行通信。
type
TMyRec = record
Name: string[255];
Age: integer;
Birthday: TDateTime;
end;
function TAppCommunication.SendRecord(const ARecordToSend: Pointer; const ARecordType: PTypeInfo): Boolean;
var
_Stream: TMemoryStream;
begin
_Stream := TMemoryStream.Create;
try
_Stream.Write(NativeInt(ARecordType), SizeOf(TTypeInfo));
_Stream.Write(NativeInt(ARecordToSend), SizeOf(ARecordToSend));
_Stream.Position := 0;
Result := SendStreamData(_Stream, TCopyDataType.cdtRecord)
finally
FreeAndNil(_Stream);
end;
end;
function TAppCommunication.SendStreamData(const AStream: TMemoryStream;
const ADataType: TCopyDataType): Boolean;
var
_CopyDataStruct: TCopyDataStruct;
begin
Result := False;
if AStream.Size = 0 then
Exit;
_CopyDataStruct.dwData := integer(ADataType);
_CopyDataStruct.cbData := AStream.Size;
_CopyDataStruct.lpData := AStream.Memory;
Result := SendData(_CopyDataStruct);
end;
function TAppCommunication.SendData(const ADataToSend: TCopyDataStruct)
: Boolean;
var
_SendResponse: integer;
_ReceiverHandle: THandle;
begin
Result := False;
_ReceiverHandle := GetRemoteReceiverHandle;
if (_ReceiverHandle = 0) then
Exit;
_SendResponse := SendMessage(_ReceiverHandle, WM_COPYDATA,
integer(FLocalReceiverForm.Handle), integer(@ADataToSend));
Result := _SendResponse <> 0;
end;
发送申请:
procedure TSenderMainForm.BitBtn1Click(Sender: TObject);
var
_AppCommunication: TAppCommunication;
_ms: TMemoryStream;
_Rec: TMyRec;
_Record: TAttrData;
begin
_AppCommunication := TAppCommunication.Create('LocalReceiverName', OnAppMessageReceived);
_ms := TMemoryStream.Create;
try
_AppCommunication.SetRemoteReceiverName('LocalReceiverNameServer');
_AppCommunication.SendString('ąčęėįšųūž123');
_AppCommunication.SendInteger(998);
_AppCommunication.SendDouble(0.95);
_Rec.Name := 'Edijs';
_Rec.Age := 29;
_Rec.Birthday := EncodeDate(1988, 10, 06);
_Record.Len := 1988;
//_ms.Write(_Rec, SizeOf(TMyRec));
//_AppCommunication.SendStreamData(_ms, TCopyDataType.cdtRecord);
_AppCommunication.SendRecord(@_rec, System.TypeInfo(TMyRec));
//_AppCommunication.SendRecord(@_Record, System.TypeInfo(TAttrData));
finally
FreeAndNil(_ms);
FreeAndNil(_AppCommunication);
end;
end;
接收申请:
procedure TReceiverMainForm.OnAppMessageReceived(const ASender
: TPair<HWND, string>; const AReceivedData: TCopyDataStruct;
var AResult: integer);
var
Info: PTypeInfo;
Data: PTypeData;
KindName: String;
SubName: String;
_TypeInfo: TTypeInfo;
_MyRec: TMyRec;
begin
....
else
begin
memLog.Lines.Add('Unknown data received.');
if (AReceivedData.dwData) = integer(TCopyDataType.cdtRecord) then
begin
memLog.Lines.Add('Record received.');
// This one works fine if "_Stream.Write(NativeInt(ARecordType), SizeOf(TTypeInfo));"
// is commented out
//_MyRec := GetProcessMyRec(ASender.Key, pointer(NativeUint(AReceivedData.lpData^)), SizeOf(TMyRec));
_TypeInfo := GetProcessTypeInfo(ASender.Key,
Pointer(AReceivedData.lpData^), SizeOf(TTypeInfo));
Info := System.TypeInfo(TMyRec);
if (_TypeInfo.Name = Info^.Name) and (_TypeInfo.Kind = Info^.Kind) then
begin
// _MyRec := GetProcessMyRec(ASender.Key, Pointer(AReceivedData.lpData^), SizeOf(TMyRec)); works
_MyRec := GetProcessMyRec(ASender.Key, pointer(NativeInt(AReceivedData.lpData^) +
SizeOf(TTypeInfo)), SizeOf(TMyRec));
ShowMessage(_MyRec.Name + ', Age: ' + IntToStr(_MyRec.Age) + ', birthday: ' +
DateToStr(_MyRec.Birthday));
end;
end;
AResult := -1;
end;
end;
问题是,如果我将 TypeInfo 和记录一起发送,我将无法读取第二个。如果我单独发送它们,我可以阅读 TypInfo 或记录。我应该修复什么才能使其正常工作?