AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Komponenten merken und später zuweisen

Ein Thema von stahli · begonnen am 29. Sep 2008 · letzter Beitrag vom 2. Okt 2008
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#1

Komponenten merken und später zuweisen

  Alt 29. Sep 2008, 15:21
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
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 08:49
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
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 09:10
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?
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 09:41
Zitat:
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
Bis auf den Smily ist das eigentlich nachvollziehbar. Der Smily gehört aber so:

Zitat:
weil die Objektvariable (bspw. Panel2) bereits ein Pointer ist. d.h. Du kannst einfach die Objektvariable übergeben, statt noch wild herumpointern zu müssen.
Nein, das eben - nach meinem Verständnis - nicht. Zu dem Zeitpunkt bei dem ich Panel2 "verschieben" möchte, ist Panel3 noch unbekannt (nicht existent). Irgendwann kenne ich dann mal Panel3 und dann möchte ich die entsprechende Zuweisung NACHHOLEN.
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.

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? 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.
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...

Stahli
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 09:57
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 Hier im Forum suchendpcollection

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
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 10:29
Zitat:
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 ?
Warum Du fragst ist eigentlich egal
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:
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
So habe ich es bei meiner Stream-Variante getan und werde es jetzt dann auch so machen. Mit so einer "Pointerumbiegung" hätte ich das nur etwas universeller und einfacher lösen können - schade, dass es mit propertys so nicht geht


Die Datei sieht übrigens dann ungefähr so aus (Bild gekürzt):

Zitat:
[Club]
ID1=39597,7929584838
ID2=39597,7966440509
HeadingLong=BV Halle 06 e.V.
HeadingShort=BV Halle 06
HeadingAbbr=HAL
EMail=
Players.Item1=Component(DPlayer1) // diese Einträge
Players.Item2=Component(DPlayer2) // werden automatisch
Players.Item3=Component(DPlayer3) // erzeugt, ebenso
Players.Item4=Component(DPlayer4) // die entsprechenden
Players.Item5=Component(DPlayer5) // Sections

[Component(DPlayer1)]
{ClassName}=TDPlayer
{Owner}=
Person.ID1=39597,7929584838
Person.ID2=39597,7969948148
Person.FirstName=André
Person.LastName=Günther
Person.NickName=Die Lippe
Person.ShortName=
Person.BirthDay=29.05.1988
Person.Kind=m
Person.Picture=Base64(Qk3GXwEAAA.................. ...................AAADYAAAA)
PersonClub.ClubLeader=0
PersonClub.HomeTeamNo=0
PersonClub.HomeTeamPos=0
PersonClub.HomeTeamLeader=0
PersonTournament.Participation=0

[Component(DPlayer2)]
{ClassName}=TDPlayer
{Owner}=
Person.ID1=39597,7929584838
Person.ID2=39597,7982654861
Person.FirstName=André
Person.LastName=Stahl
Person.NickName=Printer
Person.ShortName=
Person.BirthDay=29.05.1988
Person.Kind=m
Person.Picture=Base64(Qk3GXwEAAA.................. ...................AAADYAAAA)
PersonClub.ClubLeader=0
PersonClub.HomeTeamNo=0
PersonClub.HomeTeamPos=0
PersonClub.HomeTeamLeader=0
PersonTournament.Participation=0
Die zu benutzenden Methoden sind:
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
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 12:12
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
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 20:46
Mannooo!

Jetzt bin ich fast fertig, damit und dann lässt sich eine TComponent so nicht zuweisen

Delphi-Quellcode:
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;
Lässt sich einer Property eine Komponente zuweisen, wenn ich nur den Propertynamen habe???

Sonst kann ich wohl nochmal von neuem anfangen

Stahli
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 20:58
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#10

Re: Komponenten merken und später zuweisen

  Alt 30. Sep 2008, 21:11
GANZ exakt
Danke!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 04:59 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