![]() |
Komponenten merken und später zuweisen
Hallo alle,
ich habe eine Funktion, die zu einer bestimmten Textbezeichnung eine Komponente ermittelt und zurückgibt: xyz := GetMyComponent(DescriptionName, ClassName: String; CreateFlag: Boolean): TComponent; Existiert eine passende Komponente noch nicht, wird sie ggf. direkt in der Funktion erzeugt. Zu jeder Bezeichnung wird die gelieferte Komponente in einer StringList gespeichert und bei nochmaliger Anfrage mit der gleichen Bezeichnung aus dieser Liste gelesen. Jede Anfrage mit einer bestimmten Bezeichnung liefert also immer die gleiche Komponente zurück. Nun kann es vorkommen, dass es Aufrufe gibt, in der die Komponente noch nicht existiert aber auch noch nicht erzeugt werden darf. Hier würde ich gern eine spätere Zuweisung "vormerken" C1 := GetMyComponent('Test1', 'TTest', False); C2 := GetMyComponent('Test1', 'TTest', False); C3 := GetMyComponent('Test1', 'TTest', False); Ist eine Rückgabe derzeit nicht möglich, sollen die Parameter in einer Liste gespeichert: 'Test1' -> C1 'Test1' -> C2 'Test1' -> C3 Wird später dann durch C4 := GetMyComponent('Test1', 'TTest', True); die passende Komponente erzeugt und zurückgeliefert, soll diese Komponente auch C1, C2 und C3 zugewiesen werden. Lässt sich das realisieren und wie? Müsste ich die potentielle Rückgabeadresse mit übergeben? GetMyComponent(MY_RESULT_ADRESS: POINTER; DescriptionName, ClassName: String; CreateFlag: Boolean): TComponent; xyz := GetMyComponent(Pointer(xyz), 'Test1', 'TTest', False): TComponent; Mir fehlt der Ansatz, wie man da heran geht (Zeiger sind was fürchterliches)... Das besondere Problem (für mich) ist, dass C1, C2, und C3 - normale Variablen - Variable einer Komponente - Propertys einer Komponente (write FMyComponent bzw. write SetMyComponent) sein können. Lässt sich das (so) lösen? Danke für jede Hilfe. Hintergrund: Ich habe von TMemIniFile eine Komponente abgeleitet, die Binärdaten (Bilder) und auch Komponenten speichern und lesen kann. Das funktioniert alles super, nur die Verküpfungen der Komponenten untereinander sind noch nicht komplett geklärt. Beim Speichern und Laden von Komponenten weist TExtIniFile automatisch Sections zu, die diese Komponenten dann zum schreiben und lesen ihrer Daten verwenden. Bei Bedarf werden die benötigten Komponenten automatisch erzeugt und dann veranlasst, ihre eigenen Daten einzulesen. Die Ini-Komponente stelle ich dann hier gern bereit, falls Bedarf besteht. PS: Über den Sinn und Unsinn der Verwendung von Textdateien zur Datenspeicherung will ich keine unendliche Diskussion entfachen ;-) Für meine Zwecke ist das im Moment genau das richtige. Stahli |
Re: Komponenten merken und später zuweisen
Ich will nochmal genauer fragen:
Das Beispiel zeigt, was ich ungefähr machen will. Hier blinkt Panel2. Durch den Schalterklick wird der Zeiger von Panel3 nun auch Panel2 zugewiesen. Ab sofort blinkt Panel3, da die Instanzen von Panel2 und 3 jetzt identisch sind.
Delphi-Quellcode:
unit fPointertest;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; Panel3: TPanel; Timer1: TTimer; Button1: TButton; procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); type PObject = ^TObject; var F, T: PObject; begin F := @Panel2; T := @Panel3; FreeAndNil(Panel2); F^ := T^; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Panel2.Visible := not Panel2.Visible; end; end. Zu meinem Problem könnte ich mir das so vorstellen: procedure GetCompenentPointer(var ReadComponent: TComponent; ....); begin ... end; Wenn eine aktuelle Zuweisung einer gültigen Komponente momentan noch nicht möglich ist, merke ich mir dessen Adresse. Wenn später ein Ergebnis vorliegt (wenn nämlich die Komponente eingelesen wird, auf die vorhin schon verwiesen wurde) weise ich der GemerktenAdresse^ := DenPointerDerJetztGefundenenKomponente^ zu. Kann das so gehen - oder bin ich auf dem Holzweg? Funktioniert das auch mit einer property, die Methoden als Getter und Setter verwendet? Stahli |
Re: Komponenten merken und später zuweisen
Ich habe zwar immernoch nicht verstanden, was du eigentlich genau willst, aber folgendes kann ich dir schonmal sagen:
1. Du kannst keinen Pointer auf eine Property zeigen lassen. Einfach weil es sein kann, dass sie read/write only ist, oder dass überhaupt keine Variable dahinter steckt ;) Pointer auf Komponenten sind sowieso ... flüssiger als Wasser ... weil die Objektvariable (bspw. Panel2) bereits ein Pointer ist. d.h. Du kannst einfach die Objektvariable übergeben, statt noch wild herumpointern zu müssen. Kann es sein, dass du so eine Art "Viele miteinander verknüpfte Objekte in einer Textdatei speichern und wieder lesen können"-Code schreiben möchtest? |
Re: Komponenten merken und später zuweisen
Zitat:
Zitat:
Dazu brauche ich doch die ADRESSE des Pointers auf Panel2 und muss diese 4 Bytes jetzt auf Panel3 zeigen lassen. Panel2 selbst (und vielleicht die anderen 5 Komponentenzeiger, die noch auf eine Zuweisung auf Panel3 warten) sind jetzt nicht vmehr bekannt. Ich kann lediglich die entsprechenden Adressen der Pointer auf der Liste heraussuchen und diese dann auf Panel3 zeigen lassen.
Delphi-Quellcode:
Das trifft den Pudel auf den Kopf. Das Erzeugen der Komponenten funktioniert auch. Nur der Verweis auf eine Komponente, die erst später erzeugt wird, funktioniert noch nicht.
Kann es sein, dass du so eine Art "Viele miteinander verknüpfte Objekte in einer Textdatei speichern und wieder lesen können"-Code schreiben möchtest?
Ich hatte das alles schon mal mit einer Stream-Speicherung gelöst, indem ich den Komponenten temp. ID´s vergeben hatte und nach dem Datei-Einlesen alle Zuordnungen über eine Suche im Speicher realisiert habe. Aus verschiedenen Gründen habe ich jetzt auf eine Ini-Speicherung umgestellt und wollte die Zuordnungen möglichst eleganter lösen. Mit "normalen" Komponenten würde das sicher auch funktionieren - aber vermutlich wohl nicht mit Propertys... :evil: Stahli |
Re: Komponenten merken und später zuweisen
Darf man - aus reiner Neugier natürlich - fragen, wartum du nicht das bereits vorhandene, ,und von Delphi für die dfm-Dateien benutzte Streaming verwendest ?
So was in der Art macht aud die ![]() Wenn du es gerne selber mamchen möchtest; würde ich so vorgehen, dass ich erstmal alle Objekte auslese (ohne Verknüpfungen herzustellen) und dann die Obekte die Verknüpfungen erneut herstellen lasse. Alternativ (das hört sich nach dem an, was du schon probiert hattest) Wenn du auf etwas stößt, dass du noch nicht gelesen hast, ne ID vergeben und am Ende kann sich dann jedes Objekt (unter Angabe der ID) sein richtiges Objekt "abholen" ... Alles nicht so einfach wenns derart universell sein soll :stupid: |
Re: Komponenten merken und später zuweisen
Zitat:
Ich hatte zum Einen keinen wirklichen Zugang zu den Streaming-Funktionen gefunden. Zwar habe ich verstanden, wie das grundsätzlich funktioniert, aber das für meine Zwecke zu verwenden erschien mir zu kompliziert und nicht genau passend. - Mit meiner Version bin ich nicht an bestimmte Reihenfolgen gebunden. - Jede Komponente kann ihre Daten lesen und schreiben, wenn sie es für richtig hält. - Es können beliebige Daten geschrieben und gelesen werden (nicht nur propertys). (nach meinem Verständnis geht das mit dem dfm-Streaming nicht) Jedenfalls war der Aufwand, eine eigene Ini-Komponente abzuleiten nicht wirklich groß und ich bin mit dem Ergebnis (bis auf die Verknüpfungen bisher) sehr zufrieden... Zitat:
Die Datei sieht übrigens dann ungefähr so aus (Bild gekürzt): Zitat:
TExtIniFile.WriteComponent(...); TExtIniFile.WriteComponentList(...); TExtIniFile.ReadComponent(...); TExtIniFile.ReadComponentList(...); Es werden also auch Listen von Komponenten gespeichert und wieder hergestellt. TExtIniFile erzeugt dann automatisch die entsprechenden Einträge und Sections und veranlasst die Komponenten dann, diese beim Speichern/Lesen zu verwenden. Für Binädaten kann man TExtIniFile.WriteBase64(...); TExtIniFile.ReadBase64(...); nutzen. Was noch nicht umgesetzt ist, ist eben TExtIniFile.WriteComponentPOINTER(...); TExtIniFile.ReadComponentPOINTER(...); um Verküpfungen wieder herzustellen. Stahli |
Re: Komponenten merken und später zuweisen
Ich werde eine Methode
TExtIniFile.WriteComponentPointerProperty(Componen t, 'PropertyName', ...); TExtIniFile.ReadComponentPointerProperty(Component , 'PropertyName', ...); implementieren. Alle vorerst gescheiterten Zuweisungsversuche könnten dann in einer Liste gesammel werden (Component, PropertyName, Zielkomponenten-Bezeichnung). Später kann ich über IsPublishedProp und SetPropValue jederzeit direkt auf diese Eigenschaften zugreifen und die Werte später zuweisen. Das sollte machbar sein und ich kann auf temporäre ID´s bzw. einen zweiten Einlesedurchlauf verzichten... Eine Funktion für das Setzen "einfacher Pointer" (Variablen) benötige ich derzeit nicht, aber das könnte über die oben beschriebene Verfahrensweise (Adresse des Pointers merken) auch realisierbar sein. Mit optimistischen Grüßen Stahli |
Re: Komponenten merken und später zuweisen
Mannooo!
Jetzt bin ich fast fertig, damit und dann lässt sich eine TComponent so nicht zuweisen :-(
Delphi-Quellcode:
Lässt sich einer Property eine Komponente zuweisen, wenn ich nur den Propertynamen habe???
procedure TExtIniFile.ReadComponentProperty(PropertyComponent: TComponent;
PropertyName, Section, Ident: String); var S: String; CN: String; CCN: String; P: Integer; RC: TComponent; ExistFlag: Boolean; begin PropertyFlag := True; RC := nil; S := ReadString(Section, Ident, ''); if (S <> '') and (S <> 'Component(nil)') then begin P := Pos('(', S); Delete(S, 1, P); P := Pos(')', S); CN := Copy(S, 1, Pred(P)); CCN := ReadString('Component(' + CN + ')', '{ClassName}', ''); ExistFlag := ExistComponentName(CN); if ExistFlag then begin RC := FoundComponent(CN); end else begin PropertyList.AddObject(CN + '=' + PropertyName, PropertyComponent); end; end; if (IsPublishedProp(PropertyComponent, PropertyName)) and (Assigned(RC)) then begin SetPropValue(PropertyComponent, PropertyName, RC); // ==> Es gibt keine überladene Version von 'SetPropValue', die man mit diesen Argumenten aufrufen kann { TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray); } end; PropertyFlag := False; end; Sonst kann ich wohl nochmal von neuem anfangen :-( Stahli |
Re: Komponenten merken und später zuweisen
Einfach mal in TypInfo.pas stöbern: Da findet sich eine Prozedur namens SetObjectProp mit Parametern vom Typ TObject, String und nochmal TObject. Das ist doch exakt was du willst.
|
Re: Komponenten merken und später zuweisen
GANZ exakt :-)
Danke! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:34 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