Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TCollection-Object streamen und/od. an anderen Prozess geben (https://www.delphipraxis.net/122769-tcollection-object-streamen-und-od-anderen-prozess-geben.html)

Meta777 21. Okt 2008 23:05


TCollection-Object streamen und/od. an anderen Prozess geben
 
huhu,

habe nun schon ne ganze weile gesucht aber für mein problem keine lösung gefunden: Ich will eine TCollection-descendant an einen anderen Prozess übergeben.
Mein erster Versuch war das Object über eine WM_CopyData zu übermitteln. Wenn ich jedoch in der in der Nachrichtenbehandlung auf das TCollection-Object zugreife gibts ne AV.

Was gibt es denn neben der (dp)Collection für möglichenkeiten eine Object zu exportieren (in einen Stream schreiben)?
Oder geht es vllt. doch mit WM_CopyData und ich stell mich nur zu doof an? :stupid:

TIA

mein Versuch:
Der "Client"
Delphi-Quellcode:
var
  LCDStruct: TCopyDataStruct;
  LRes: Integer;
begin
  LRes := 0;

  LCDStruct.dwData := DAM_daLoad;
  LCDStruct.lpData := @ACollection;
  LCDStruct.cbData := SizeOf(ACollection);

  LRes := SendMessage(AHWnd, WM_COPYDATA, Application.Handle, Integer(@LCDStruct));
Der "Server"
Delphi-Quellcode:
procedure TfrmMain.WMCopyData(var Msg: TMessage);
begin
  MyActiveChild.MyColl.Assign(TMyCollection(PCopyDataStruct(Msg.LParam)^.lpData^));    <- Hier gibts ne AV
end;

jfheins 22. Okt 2008 06:49

Re: TCollection-Object streamen und/od. an anderen Prozess g
 
Naja, du überginst ja nur nen Zeiger auf die Collection, deshalb versuchst du dann auch im 2. Prozess auf etwas zuzugreifen das nicht dir gehört.

Du müsstest schon erst die Collection streamen (z.B. in nen MemoryStream) und dann übergeben ;)

Die dpCollection müsste bereits eine savetoStream-Methode haben, ansonsten: http://delphicikk.atw.hu/listaz.php?id=1361&oldal=32 ;)

Meta777 23. Okt 2008 18:16

Re: TCollection-Object streamen und/od. an anderen Prozess g
 
hi,

habe nun versucht die Collection in ein MemoryStream zu schreiben. Soweit sogut. jedoch funktioniert das "Auslesen" nicht. Beim Server versuche ich folgendes:
Delphi-Quellcode:
procedure TfrmMain.WMCopyData(var Msg: TWMCopyData);
var
  LMS: TMemoryStream;
begin
  LMS := TMemoryStream(Msg.CopyDataStruct^.lpData^);    <- lpData zeigt wo anders hin!??
  LMS.Position := 0;                                    <- AV
end;
lpData zeigt immer auf eine andere Adresse als ich im Client angebe. Deswegen kracht es denn auch mit ner AV.
Der Cleint macht das:

Delphi-Quellcode:
var
  LCDStruct: TCopyDataStruct;
  LMS: TMemoryStream;
begin

  LMS := TMemoryStream.Create;
  try
    WriteCollection(LMS, ACollection);

    LCDStruct.dwData := DAM_daViewLoad;
    LCDStruct.lpData := @LMS;
    LCDStruct.cbData := LMS.Size;

    LRes := SendMessage(AHWnd, WM_COPYDATA, Application.Handle, Integer(@LCDStruct));
....
end;
weiß jmd. wo mein Fehler liegt? :wall:


Shalom

jfheins 23. Okt 2008 18:24

Re: TCollection-Object streamen und/od. an anderen Prozess g
 
Ja, ich :mrgreen:

Du benutzt nun einen MemoryStream statt der Collection. Schonmal auf dem richtigen Weg.

Aber du übergibst einen Pointer auf einen Pinter auf den Stream. (Ein Objekt ist bereits ein Pointer und @LMS ... ;) )

Versuch mal
Delphi-Quellcode:
var
  LCDStruct: TCopyDataStruct;
  LMS: TMemoryStream;
begin

  LMS := TMemoryStream.Create;
  try
    WriteCollection(LMS, ACollection);

    LCDStruct.dwData := DAM_daViewLoad;
    LCDStruct.lpData := Pointer(LMS);
    LCDStruct.cbData := LMS.Size;

    LRes := SendMessage(AHWnd, WM_COPYDATA, Application.Handle, Integer(@LCDStruct));
....
end;
Und dann
Delphi-Quellcode:
procedure TfrmMain.WMCopyData(var Msg: TWMCopyData);
var
  LMS: TMemoryStream;
begin
  LMS := TMemoryStream(Msg.CopyDataStruct^.lpData);    <- lpData zeigt wo anders hin!?? 
  LMS.Position := 0;                                    <- AV
// LMS ist Read-Only und temporär ==> Evtl. Kopie machen
end;
Edit: Wobei das auch nicht funktionieren dürfte - denn der Objektzeiger zeigt sicherlich nicht direkt auuf den Stream ..
Du solltest also nur die eigentlichen daten verschicken.

Benutze TStringStream, da kannst du dann diirekt den String verschicken ;)
Delphi-Quellcode:
var
  LCDStruct: TCopyDataStruct;
  LMS: TStringStream;
begin

  LMS := TStringStream.Create('');
  try
    WriteCollection(LMS, ACollection);

    LCDStruct.dwData := DAM_daViewLoad;
    LCDStruct.lpData := PChar(LMS.getString) // oder so
    LCDStruct.cbData := LMS.Size;

    LRes := SendMessage(AHWnd, WM_COPYDATA, Application.Handle, Integer(@LCDStruct));
....
end;

Meta777 23. Okt 2008 22:10

Re: TCollection-Object streamen und/od. an anderen Prozess g
 
Danke!

Hatte einwenig gedauert bis ich herrausgefunden habe das ich den String mit .WriteString() wieder in den TStringStream schreiben muss... :wall:
Funzt jetzt super, sogar mit den Objekten und deren "Child"-Objekte in den Items (Hät ich nicht gedacht, dass das auf Anhieb klappt.)

Gottes Segen!


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz