AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Problem beim Senden eines Records mit CopyDataStruct
Thema durchsuchen
Ansicht
Themen-Optionen

Problem beim Senden eines Records mit CopyDataStruct

Ein Thema von mac.cat · begonnen am 24. Nov 2007 · letzter Beitrag vom 24. Nov 2007
Antwort Antwort
Seite 1 von 2  1 2      
mac.cat

Registriert seit: 2. Sep 2007
9 Beiträge
 
#1

Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 02:08
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 >klick<.

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:
type
   TRegisterRecord = packed record
      appletname: string;
      version: string;
      ersteller: string;
      release: string;
      handle: thandle;
   end;
   PRegisterRecord = ^TRegisterRecord;
Variablen:
Delphi-Quellcode:
  private
     FSaveRecord : TRegisterRecord;
     FRegisterRecord : PRegisterRecord;
Properties:
Delphi-Quellcode:
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 }
Und schlussendlich meine Funktion:
Delphi-Quellcode:
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;
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.

Ich hoffe, ihr könnt mir bei meinem Problem helfen

mfg mac.cat
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 02:23
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.
  Mit Zitat antworten Zitat
mac.cat

Registriert seit: 2. Sep 2007
9 Beiträge
 
#3

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 02:38
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:
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;
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 "[".

mfg mac.cat
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 08:01
Dann mach es so:
Delphi-Quellcode:
Type
  TMyString = String[255];

  TMyClass = Class
  Public
    Property MyProperty : TMyString Read GetMyString Write SetMyString;
  End;
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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von ghost007
ghost007

Registriert seit: 31. Okt 2005
Ort: München
1.024 Beiträge
 
Delphi 7 Personal
 
#5

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 10:56
Zitat von alzaimar:
Dann mach es so:
Delphi-Quellcode:
Type
  TMyString = String[255];

  TMyClass = Class
  Public
    Property MyProperty : TMyString Read GetMyString Write SetMyString;
  End;
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.
Hi,
hab deinen vorschlag mal aufgegriffen. Welche Funktion hat die zeile

  TMyClass = Class ?

MfG - Ghost007
Christian
Es gibt möglich Dinge und unmöglich Dinge.
Für unmögliche braucht man lediglich etwas länger.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#6

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 13:02
Zitat von ghost007:
Hi,
hab deinen vorschlag mal aufgegriffen. Welche Funktion hat die zeile
  TMyClass = Class MfG - Ghost007
Äh... Klasse deklarieren?
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 13:05
Man sollte den privaten Member, den Getter und den Setter aber auch deklarieren
Markus Kinzler
  Mit Zitat antworten Zitat
mac.cat

Registriert seit: 2. Sep 2007
9 Beiträge
 
#8

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 14:00
Danke, für den Vorschlag. Ich werde es mal testen und mich dann wieder melden
  Mit Zitat antworten Zitat
Benutzerbild von ghost007
ghost007

Registriert seit: 31. Okt 2005
Ort: München
1.024 Beiträge
 
Delphi 7 Personal
 
#9

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 20:30
Zitat von alzaimar:
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.
Wie serialisiert man eine klasse o.O (sorry, hab noch nie mit klassen gearbeitet).
Hast du evtl n beispiel?

MfG - Ghost007
Christian
Es gibt möglich Dinge und unmöglich Dinge.
Für unmögliche braucht man lediglich etwas länger.
  Mit Zitat antworten Zitat
mac.cat

Registriert seit: 2. Sep 2007
9 Beiträge
 
#10

Re: Problem beim Senden eines Records mit CopyDataStruct

  Alt 24. Nov 2007, 20:37
Danke alzaimar!
Dein Lösungsvorschlag aus Beitrag #4 hat funktioniert!
DankeDankeDankeDanke
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:49 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