Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Komponenten zut Laufzeit erzeugen/darauf zugreifen (https://www.delphipraxis.net/65141-komponenten-zut-laufzeit-erzeugen-darauf-zugreifen.html)

SnuffMaster23 12. Mär 2006 21:22


Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
Hallo,

Ich hab gleich zwei Fragen.

1. Wieso funktionert
Delphi-Quellcode:
procedure AddPanel;
var NewPanel: TPanel;
begin
   NewPanel := TPanel.Create(Form1);
end;
?

2. Wie kann ich auf das neu erzeucgte Panel zugreifen, wenn ich einen Zeiger habe? So nach der Art:
Delphi-Quellcode:
var
  Pointers:  array[Byte] of Pointer;
  PanelCount: Integer;

  .
  .
  .

procedure AddPanel;
var NewPanel: TPanel;
begin
  NewPanel := TPanel.Create(Form1);
  Pointers[PanelCount] := @NewPanel;
  Inc(PanelCount);
end;
(Den 2. Code hab ich jetzt nicht getestet)

Den Zeiger kann ich nicht mit (Pointers[x]^ as TPanel) oder TPanel(Pointers[x]^) in TPanel casten, da krieg ich ne Fehlermeldung. Müsste ich mir da nen Typ PPanel = ^TPanel definieren und den dann für das Array nehmen?

Außerdem gibts die Variable NewPanel ja nur in der Zeit, in der AddPanel ausgeführt wird. Trotzdem bleiben die ganzen Panels da.

Ich hab sowas bisher mit einem globalen array[Byte] of TPanel gemacht und das statt der lokalen Variable verwendet, aber elegant wäre anders...

Greetz
Snuffi

SirThornberry 12. Mär 2006 21:25

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
anstelle von
Delphi-Quellcode:
Panel(Pointers[x]^)
einfach
Delphi-Quellcode:
TPanel(Pointers[x])
denn ein Object ist bereits ein Pointer auf speicher.

Und warum erstens funktioniert: Weil der Source richtig ist. Gegenfrage: Warum sollte es nicht funktonieren?

Luckie 12. Mär 2006 21:26

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
Wie man visuelle VCL Objekte zur Laufzeit erzeugt und mit ihnen arbeitet, wurde schon oft im Forum besprochen. Bitte benutz die Suche.

Desweiteren warum nicht ein Array of TLable?

SnuffMaster23 12. Mär 2006 21:35

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
@SirThornberry:
Zitat:

Zitat von SirThornberry
Gegenfrage: Warum sollte es nicht funktonieren?

Dass mir die Prozedur ein neues Panel beschert, ist klar. Aber nach der Prozedur?
Zitat:

Zitat von SnuffMaster23
Außerdem gibts die Variable NewPanel ja nur in der Zeit, in der AddPanel ausgeführt wird.

@Luckie:
1. Sorry, an die Suche denk ich nicht so oft... ich werds in Zukunft versuchen!
2. Das mit dem festen Array möchte ich nicht weil das etwas unflexibel bzw. nach oben beschränkt ist (obwohl, 256 Panels sind mehr als genug). Außerdem benötigt es meist unnötig viel Speicher, da man wohl kaum die 256 Panels braucht.
Mit dynamischen Arrays kenn ich mich nicht aus, grad vorhin hab ich auch was gelesen, dass Delphi bei einer Größenänderung (des Arrays) ganz schön Speicher verschwendet.

SirThornberry 12. Mär 2006 21:39

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
zu punkt1: Das Panel bleibt auch nach der Procedure erhalten weil dort dynamich speicher angefordert wird. Letzendlich ist ein TObject ja nur ein Pointer und dieser Pointer ist auch nur lokal gültig. Aber wo der Pointer hinzeigt, das ist immer gültig. Und wenn du TObject.Create aufrufst wird eben dynamich speicher angefordet, eben als würdest du mit New, StrAlloc etc. arbeiten.

SnuffMaster23 12. Mär 2006 21:41

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
Wenn das so ist, könnte ich ja auch nur
Delphi-Quellcode:
procedure AddPanel;
begin
  TPanel.Create(Form1);
end;
schreiben, oder?. Allerdings kann ich dann nie wieder dareuf zugreifen...

SirThornberry 12. Mär 2006 21:45

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
genau, du könntest es so erzeugen aber kannst dann nicht darauf zugreifen. Deswegen gibt es Leute welche mit der uneleganten Methode "FindComponent" danach das Panel suchen. Oder es gibt die eleganteren Methoden wie:
- In Array speichern welches nicht lokal ist
- in eine Liste speichern welche nicht lokal ist (TList, TObjectList etc.)

im übrigen gehört zu einem TObject.Create auch immer ein ObjectInstanz.Free
Wenn du also irgendwann ein Object erstellt hast solltest du wenn du es nicht mehr benötigst auch mit ".Free" wieder freigeben.

SnuffMaster23 12. Mär 2006 21:49

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
findet FindComponent nicht nur Komponenten, die zur Entwurfszeit ins Formular gesetzt wurden?

Und für was gibts denn den Eigentümer (hier Form1)? Wenn das freigegeben wird sollten doch die Panels mit-freigegeben werden, das ist doch der Trick an der ganzen Owner-Sache.

//Edit: Übrigens, das mit dem casten ohne dereferenzieren klappt!! :mrgreen: :mrgreen:

noch ein
//Edit: Wenn ein TObject nur ein Zeiger ist, braucht dann ein array[Byte] of TPanel genauso viel Platz wie ein auuay[Byte] of Pointer?

SirThornberry 12. Mär 2006 21:55

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
natürlich werden auch die Panels auch freigegeben wenn der Owner frei gegeben wird. Allerdings ist das eben nicht die sauberste Variante.
Und "FindComponent" findet nicht nur Komponenten die zur Designzeit auf dem Form liegen. Auch dort spielt wieder der Owner eine Rolle. Durch
Delphi-Quellcode:
TComponent.Create(Form1);
Trägt sich die erzeugte Instanz bei Form1 ein und somit funktioniert auch
Delphi-Quellcode:
Form1.FindComponent('Componentenname');
Und das Form1 kann man meist weglassen da in den meistne fällen "Form1 = Self" und Self muss man nicht zwangsläufig schreiben.

Das heißt alle Komponenten die du zur Designzeit aufs Formular packst bekommen als Owner das Formular (egal ob sie auf einem Panel liegen oder nicht)

SnuffMaster23 12. Mär 2006 21:59

Re: Komponenten zut Laufzeit erzeugen/darauf zugreifen
 
Was meinst du mit
Zitat:

Zitat von SirThornberry
nicht die sauberste Variante

Das Ding wird doch freigegeben und gut ist. Natürlich wirds beim Code-lesen nicht so ganz klar, aber ich verweis da jetzt mal auf deine Signatur...


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:32 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