![]() |
Problem beim Senden eines Records mit CopyDataStruct
Hi,
ich bin momentan dabei eine Komponente zu schreiben, bei der man verschiedene Werte angibt, die daraufhin an eine bestimmte Anwendung in Form eines Records geschickt werden. Ich habe mich dabei an diesem Tutorial hier orientiert ![]() Solange der Rekord nur 1 String enthält, funktioniert das ganze auch noch super. Bei mehreren gibt es einen Access Violation Error. Ich poste am Besten mal ein wenig meines Codes.. Mein Rekord:
Delphi-Quellcode:
Variablen:
type
TRegisterRecord = packed record appletname: string; version: string; ersteller: string; release: string; handle: thandle; end; PRegisterRecord = ^TRegisterRecord;
Delphi-Quellcode:
Properties:
private
FSaveRecord : TRegisterRecord; FRegisterRecord : PRegisterRecord;
Delphi-Quellcode:
Und schlussendlich meine Funktion:
published
property Appletname: String read FSaveRecord.appletname write FSaveRecord.appletname; property Version: String read FSaveRecord.version write FSaveRecord.version; property Ersteller: String read FSaveRecord.ersteller write FSaveRecord.ersteller; property Releasedatum: String read FSaveRecord.release write FSaveRecord.release; { Published-Deklarationen }
Delphi-Quellcode:
Momentan wird nur 1 String in den Record geschrieben. Die anderen sind auskommentiert. Wenn ich jetzt jedoch einen weiteren hinzufüge, gibt es beim Senden einen AV Error.
function TG15Center.registerApp: boolean;
var cds: TCopyDataStruct; hWnd: THandle; begin GetMem(FRegisterRecord, sizeof(TRegisterRecord)); FRegisterRecord.appletname := FSaveRecord.appletname; //FRegisterRecord.version := FSaveRecord.version; //FRegisterRecord.ersteller := FSaveRecord.ersteller; //FRegisterRecord.release := FSaveRecord.release; //FRegisterRecord.handle := FSaveRecord.handle; try cds.dwData := 0; cds.cbData := sizeof(TRegisterRecord); cds.lpData := FRegisterRecord; hWnd := FindWindow(nil, 'Applet Center - Starhawk'); if hwnd = 0 then begin Result := false; exit; end; SendMessage(hWnd, WM_COPYDATA, FRegisterRecord.handle, Integer(@cds)); finally FreeMem(FRegisterRecord, sizeof(TRegisterRecord)); end; Result := true; end; Ich hoffe, ihr könnt mir bei meinem Problem helfen ;) mfg mac.cat |
Re: Problem beim Senden eines Records mit CopyDataStruct
WM_COPYDATA kopiert nur das, wohin lpData in deiner Applikation zeigt in der Größe, wie es cbData angibt. Dein Record enthält aber Strings und die haben eine Variable länge und werden dort nur als Adresse (in deinem lokalen Speicher) abgelegt. Somit versendest du nur 4 Adressen welche in deiner Applikation gültig sind, aber beim Empfänger selber steht dort Müll (wenn überhaupt). Du versendest also nicht die Daten selber, sondern nur Pointer. Du kannst ja mal überprüfen was SizeOf() dir für den Record ausgibt, der Debugger dürfte dir da auch nur mickrige 20 Bytes ausgeben - und das ist für 4 Strings und ein Handle eindeutig zu wenig. Das wäre aber mal eine wirklich gute Kompression, weil diese Grösse ändert sich nicht, egal wieviel zu zuweist. Ein Record hat die Eigenschaft zur Laufzeit eine konstante Grösse zu haben.
Abhilfe: Lege entweder eine definierte variable Struktur im Speicher an, wo die Strings nacheinander folgen und du sie auch sicher wieder trennen kannst. Diesen kompletten Speicherbereich kannst du dann versenden. Das wird dann aber nicht mit einerm Record funktioniert, da dieser - wie schon gesagt - konstant ist. Andere Möglichkeit: beschränke dich auf eine maximale Stringlänge. Dann definiere diese als die Grösse der Strings und sie würden auch an Ort und Stelle in dem Record liegen. Gutes Beispiel für ein 255 Zeichenstring wäre der ShortString. Für die letzte Methode bräuchtest du nur die Record-Definition ändern und string durch ShortString ersetzen. Damit wird dann dein Record ungemein grösser (siehe SizeOf()), aber auch die Strings dürfen nur noch maximal 255 Zeichen enthalten. /EDIT: In deinem Tutorial wird auch ein String[255] genutzt (entspricht genau dem ShortString) und darin liegt der Grund. |
Re: Problem beim Senden eines Records mit CopyDataStruct
Hey, schön, dass einem selbst noch um diese Uhrzeit geholfen wird^^
Also das mit dem String auf 255 beschränken kam mir auch schon in den Sinn. Dabei gab es aber ein kleines Problem mit den Properties. für die Zeilen
Delphi-Quellcode:
zeigt er mir dann logischerweise an, dass es unkompatible Typen sind. Die Frage ist nur, wie ändere ich das? String einfach durch Shortstring zu ersetzen brachte gar nichts. String[255] hinzuschreiben verursachte auch eine Fehlermeldung, aber diese wegen unerwartetem Zeichen "[".
property Appletname: String read FSaveRecord.appletname write FSaveRecord.appletname;
property Version: String read FSaveRecord.version write FSaveRecord.version; property Ersteller: String read FSaveRecord.ersteller write FSaveRecord.ersteller; property Releasedatum: String read FSaveRecord.release write FSaveRecord.release; mfg mac.cat |
Re: Problem beim Senden eines Records mit CopyDataStruct
Dann mach es so:
Delphi-Quellcode:
Oder serialisiere deine Klasse, das ist eh besser. Du kannst dafür die Klasse von TPersistent ableiten und die zu übertragenden Eigenschaften als Published deklarieren. So werden übrigens Delphi-Formulare (*.DFM) abgelegt.
Type
TMyString = String[255]; TMyClass = Class Public Property MyProperty : TMyString Read GetMyString Write SetMyString; End; |
Re: Problem beim Senden eines Records mit CopyDataStruct
Zitat:
hab deinen vorschlag mal aufgegriffen. Welche Funktion hat die zeile
Delphi-Quellcode:
?
TMyClass = Class
MfG - Ghost007 |
Re: Problem beim Senden eines Records mit CopyDataStruct
Zitat:
|
Re: Problem beim Senden eines Records mit CopyDataStruct
Man sollte den privaten Member, den Getter und den Setter aber auch deklarieren
|
Re: Problem beim Senden eines Records mit CopyDataStruct
Danke, für den Vorschlag. Ich werde es mal testen und mich dann wieder melden ;)
|
Re: Problem beim Senden eines Records mit CopyDataStruct
Zitat:
Hast du evtl n beispiel? MfG - Ghost007 |
Re: Problem beim Senden eines Records mit CopyDataStruct
Danke alzaimar!
Dein Lösungsvorschlag aus Beitrag #4 hat funktioniert! DankeDankeDankeDanke :hello: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz