AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Object dynamisch in einem Array erzeufen

Ein Thema von gangs-taas · begonnen am 11. Okt 2010 · letzter Beitrag vom 14. Okt 2010
Antwort Antwort
Seite 1 von 3  1 23   
gangs-taas

Registriert seit: 24. Mär 2009
364 Beiträge
 
#1

Object dynamisch in einem Array erzeufen

  Alt 11. Okt 2010, 19:48
Hey,
ich möchte gerne Shapes dynamisch erzeugen.
Dafür habe ich mir gedacht ich mach das in einem Array.
Ich mach das aber in einer zweiten Unit (um das schön objectorientiert zu machen ..).
Ich hab das wie folgt umgesetzt ABER trotzdem haben nach dem erzeugen alle Einträge in meinem Array den wert "Nil" und wenn ich damit weiter arbeiten möchte bekomme ich fehlermeldungne (weil ja nichts da ist zum drauf zugreifen .. )
könnt ihr mir sagen woran es liegt ?

Delphi-Quellcode:
procedure TVerw.Add_Ufo(Starty,StartX,Geschwin : integer;
                        Sender :TComponent; Unterlage : TWinControl);
begin
  SetLength(Ufo_Arr,Length(Ufo_Arr) + 1 );
  Ufo_Arr[Length(Ufo_Arr)] := TUfo.Create(StartX,StartY,Geschwin,Sender);
  Ufo_Arr[Length(Ufo_Arr)].Parent := Unterlage; // => das Form auf dem es Dargestellt werden soll
  Ufo_Arr[Length(Ufo_Arr)].Name := 'Ufo' + IntToStr(Length(Ufo_Arr)) ;
  Ufo_Arr[Length(Ufo_Arr)].Shape :=stCircle;
  Ufo_Arr[Length(Ufo_Arr)].Brush.Color := ClBlue ;
  Ufo_Arr[Length(Ufo_Arr)].Width := Ufo_Breite ;
  Ufo_Arr[Length(Ufo_Arr)].Height := Ufo_hoehe ;
  Ufo_Arr[Length(Ufo_Arr)].Show;

end;
außerdem habe ich die Create Routine ein wenig verändert, aber ich denke nicht, dass es daran liegt ..
nur zur sicherheit hier die veränderte Create Routine :
Delphi-Quellcode:
 
// Tufo ist vom Type TShape

 constructor TUfo.Create(StartKoX, StartKoY, Geschwindigkeit: integer; Owner : TComponent );
  begin
  inherited Create(Owner) ;
    Left := StartKoX ;
    Top := StartKoY ;
    Rich_Arr[1] := Geschwindigkeit ;
    Rich_Arr[2] := 0 ;
    Muenze := false ;
  end;

Geändert von gangs-taas (11. Okt 2010 um 19:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von nachti1505
nachti1505

Registriert seit: 7. Apr 2007
188 Beiträge
 
Delphi 7 Enterprise
 
#2

AW: Object dynamisch in einem Array erzeufen

  Alt 11. Okt 2010, 20:04
Dynamische Arrays sind imho Nullbasiert -->

Ufo_Arr[Length(Ufo_Arr)-1] := TUfo.Create(StartX,StartY,Geschwin,Sender);
  Mit Zitat antworten Zitat
gangs-taas

Registriert seit: 24. Mär 2009
364 Beiträge
 
#3

AW: Object dynamisch in einem Array erzeufen

  Alt 11. Okt 2010, 20:08
stimmt natürlich
immer mach ich die gleichen blöden fehlöer :/
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Object dynamisch in einem Array erzeufen

  Alt 11. Okt 2010, 21:03
Wenn du OOP machen möchtest dann nimm dafür die richtige Klasse TObjectList
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#5

AW: Object dynamisch in einem Array erzeufen

  Alt 13. Okt 2010, 01:02
Hast du schon mal über "Templates" nachgedacht:

Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Unit : t_TypedObjectList //
// Quelle: www.dummzeuch.de/delphi/object_pascal_templates/deutsch.html //
////////////////////////////////////////////////////////////////////////////////
// Erstellt von: David Martens //
// Erstellt am : 10.11.2008 //
// Beschreibung: Delphi-"Template" zur Erstellung typisierter Listen //
////////////////////////////////////////////////////////////////////////////////
// Geändert von: //
// Geändert am : //
////////////////////////////////////////////////////////////////////////////////

{$IFNDEF LIST_TEMPLATE_}
unit t_TypedObjectList;

interface

{: These units must be added to the uses clause of any class built on this template }
uses
  Classes;

{: These types must be declared for each class built on this template }
type
  {: the ancestor class for the template, can be TObject or TInterfacedObject
     or anything else you like}

  _LIST_ANCESTOR_ = TObject;
  {: Container type used to actually store the items: TList or TInterfacelist }
  _LIST_CONTAINER_ = TList;
  {: The native item type of the list container (Pointer for TList, IInterface for TInterfaceList}
  _LIST_CONTAINER_ITEM_TYPE_ = pointer;
  {: The item type to be stored in the list }
  _ITEM_TYPE_ = TObject;

{$ENDIF LIST_TEMPLATE_}

{$IFNDEF LIST_TEMPLATE_SECOND_PASS_}

type
  _LIST_TEMPLATE_ = class(_LIST_ANCESTOR_)
  private
    {: This actually stores the items }
    FItems: _LIST_CONTAINER_;
    {: Getter function for Items property }
    function _GetItems(_Idx: integer): _ITEM_TYPE_;
  protected
    {: Frees an item (does nothing here, must be overwritten }
    procedure FreeItem(_Item: _ITEM_TYPE_); virtual;
  public
    {: Creates a list for storing items }
    constructor Create;
    {: Calls FreeItem for alle items and frees the list }
    destructor Destroy; override;
    {: Returns the number of items stored in the list }
    function Count: integer;
    {: Deletes all items from the list without calling FreeItem }
    procedure DeleteAll;
    {: Exchanges the two items at index Idx1 and Idx2 }
    procedure Exchange(_Idx1, _Idx2: integer);
    {: removes the item with index Idx from the list and returns it }
    function Extract(_Idx: integer): _ITEM_TYPE_;
    {: Calls FreeItem for all items and removes them from the list }
    procedure FreeAll;
    {: inserts an item into the list and returns its index }
    procedure Insert(_Idx: integer; _Item: _ITEM_TYPE_); virtual;

    function Add(_Item: Pointer): integer;
    {: allows accessing the items in the list by index }
    property Items[_Idx: integer]: _ITEM_TYPE_ read _GetItems; default;
  end;

{$ENDIF LIST_TEMPLATE_SECOND_PASS_}

{$IFNDEF LIST_TEMPLATE_}
{$DEFINE LIST_TEMPLATE_SECOND_PASS_}
implementation
{$ENDIF LIST_TEMPLATE_}

{$IFDEF LIST_TEMPLATE_SECOND_PASS_}

{ _LIST_TEMPLATE_ }

function _LIST_TEMPLATE_.Add(_Item: Pointer): integer;
begin
  Result := FItems.Add(_LIST_CONTAINER_ITEM_TYPE_(_Item));
end;

function _LIST_TEMPLATE_.Count: integer;
begin
  Result := FItems.Count;
end;

constructor _LIST_TEMPLATE_.Create;
begin
  inherited Create;
  FItems := _LIST_CONTAINER_.Create;
end;

procedure _LIST_TEMPLATE_.DeleteAll;
begin
  FItems.Clear;
end;

destructor _LIST_TEMPLATE_.Destroy;
var
  i: integer;
  Item: _ITEM_TYPE_;
begin
  if Assigned(FItems)
  then
  begin
    for i := 0 to FItems.Count - 1
    do
    begin
      Item := _ITEM_TYPE_(FItems[i]);
      FreeItem(Item);
    end;
  end;
  FItems.Free;
  inherited;
end;

procedure _LIST_TEMPLATE_.Exchange(_Idx1, _Idx2: integer);
begin
  FItems.Exchange(_Idx1, _Idx2);
end;

function _LIST_TEMPLATE_.Extract(_Idx: integer): _ITEM_TYPE_;
begin
  Result := _ITEM_TYPE_(FItems[_Idx]);
  Fitems.Delete(_Idx);
end;

procedure _LIST_TEMPLATE_.FreeAll;
var
  i: integer;
begin
  for i := 0 to FItems.Count - 1
  do
  begin
    FreeItem(_ITEM_TYPE_(FItems[i]));
  end;
  FItems.Clear;
end;

procedure _LIST_TEMPLATE_.FreeItem(_Item: _ITEM_TYPE_);
begin
  // do nothing, override if the items must be freed
end;

function _LIST_TEMPLATE_._GetItems(_Idx: integer): _ITEM_TYPE_;
begin
  Result := _ITEM_TYPE_(FItems[_Idx]);
end;

procedure _LIST_TEMPLATE_.Insert(_Idx: integer; _Item: _ITEM_TYPE_);
begin
  FItems.Insert(_Idx, _LIST_CONTAINER_ITEM_TYPE_(_Item));
end;

{$ENDIF LIST_TEMPLATE_SECOND_PASS_}

{$DEFINE LIST_TEMPLATE_SECOND_PASS_}

{$IFNDEF LIST_TEMPLATE_}
{$WARNINGS OFF}
end.
{$ENDIF LIST_TEMPLATE_}
Und hier ist ein kleines Beispiel um die Anwendung zu demonstrieren:

Das Objekt was in der Liste gespeichert werden soll:
Delphi-Quellcode:
unit u_FilterItem;

interface

type
  TFilterItem = class
  strict private
    FHeight : integer;
    FTop : integer;

    FControl : TControl;
    ...
  public
    constructor Create(aParent : TWinControl;
                       iName : integer;
                       Top : integer;
                       OnClick : TNotifyEvent;
                       OnChangeEvent : TNotifyEvent);

    destructor Destroy; override;

    ...

    property Height : integer read FHeight write SetHeight;
    property Top : integer read FTop write SetTop;
    ...
  end;

implementation

und er ganze Rest.......
also ein ganz normales Objekt.
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Erstellt von: David Martens //
// Erstellt am: 10.11.2008 //
// Beschreibung: typisierte Listklasse unter Verwendung eines //
// Delphi-"Templates" //
// //
// In der "Listklasse" ist eine "Kontainerklasse" enthalten, //
// die die eigentliche Liste enthält. //
// //
// weitere Beschreibung in der Implementierung //
////////////////////////////////////////////////////////////////////////////////
unit u_FilterItemList;

interface

uses
  Classes,
  // Unit mit Klasse für _ITEM_TYPE_ (eine ganz normale Klasse)
  u_FilterItem;

// Kompilerdirektive für das Template
{$DEFINE LIST_TEMPLATE_}

type
  // Vorfahr der "Listklasse"
  _LIST_ANCESTOR_ = TObject;
  // Vorfahr der "Kontainerklasse", sollte ein Nachfahr von TList sein
  _LIST_CONTAINER_ = TList;
  // Typ des Items in der "Kontainerklasse" (z.B.: Pointer für TList, IInterface für TInterfaceList}
  _LIST_CONTAINER_ITEM_TYPE_ = pointer;
  // Item der typisierten Klasse, dieser Typ wird von der Klasse ausgegeben
  _ITEM_TYPE_ = TFilterItem;

// Verzeichnis: \Delphi\Komponenten\Templates nicht in Umgebungsvariablen vorhanden daher so:

// 1. Template-aufruf: erstellt den Kopf der _LIST_TEMPLATE_ Klasse anhand der oben gemachten Angaben
{$INCLUDE '..\Templates\t_TypedObjectList.pas'}

type
  // "Umbenennung" von _LIST_TEMPLATE_ und weitere spezielle Eigenschaften für die Klasse
  TFilterItemList = class(_LIST_TEMPLATE_)
  protected
    // muss implementiert werden, falls die Items freigegeben werden müssen (destructor Aufruf)
    procedure FreeItem(_Item: _ITEM_TYPE_); override;
  end;

implementation

// 2. Template-aufruf: implementiert die _LIST_TEMPLATE_ Klasse anhand der oben gemachten Angaben
{$INCLUDE '..\Templates\t_TypedObjectList.pas'}


// Implementierung der speziellen Eigenschaften der Klasse

{ TFilterItemList }

procedure TFilterItemList.FreeItem(_Item: _ITEM_TYPE_);
begin
  _Item.Free;

  inherited;
end;

end.
Zum Schluß, wie es angewendet wird:
Delphi-Quellcode:
    FFilterListe : TFilterItemList;

...

  if FFilterListe.Count > 0 then
  begin
    NewTop := FFilterListe.Items[FFilterListe.Count - 1].Top +
              FFilterListe.Items[FFilterListe.Count - 1].Height;
  end;
Kein typecating mehr
  Mit Zitat antworten Zitat
gangs-taas

Registriert seit: 24. Mär 2009
364 Beiträge
 
#6

AW: Object dynamisch in einem Array erzeufen

  Alt 13. Okt 2010, 12:18
Hey,
viele Dank, für die sehr ausführlichen antworten .

zu TObjectList :
Ich sehe dort ehrlich gesagt nicht unbedigt sooo den vorteil im gegensatz zu einem Array ..
ist vllt einfacher elemente zu löschen o.ä. aber ansonsten seh ich keinen vorteil

zu Templates

ich denke, das ist kompizierte, als es sein muss,
vorallem, weil ich kein hochausgeklügeltes prgramm schreib, sondern äh.. ich einfach froh bin, wenn es hinterher das macht, was ich will
ich muss nicht alle lücken abdecken ..

trotzdem vielen dank
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.018 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Object dynamisch in einem Array erzeufen

  Alt 13. Okt 2010, 12:24
Noch ein Tipp zu Arrays: wann immer möglich solltest Du Low() und High() verwenden, damit bleibst Du garantiert innerhalb der Array-Grenzen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Object dynamisch in einem Array erzeufen

  Alt 13. Okt 2010, 12:41
Ich dachte du wolltest das "schön objektorientiert" machen.

Ein Array ist aber imho nicht oop
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#9

AW: Object dynamisch in einem Array erzeufen

  Alt 13. Okt 2010, 14:53
Diese Arrays für Komponenten oder Controls sind doch Käse!
Sorry, aber ich muss immer wieder feststellen, dass viele die Kurve zu OOP nicht kriegen.

Dabei gibt es neben TObjectList auch die Klasse TComponent.
Damit kann man die Objekte sehr elegant und mit geringstem Aufwand verwalten.

Hier ein Beispiel wie man TComponent als Ersatz für das Array benützt:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    ButtonControlsErzeugen: TButton;
    ButtonControlsLoeschen: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ButtonControlsErzeugenClick(Sender: TObject);
    procedure ButtonControlsLoeschenClick(Sender: TObject);
  private
    { Private-Deklarationen }
    FMyList : TComponent; // Ersatz für Array
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
   FMyList := TComponent.Create(Self);
   // Besitzer ist das Formular; FMyList braucht also nicht freigegeben werden
end;

procedure TForm1.ButtonControlsErzeugenClick(Sender: TObject);
var
   i : Integer;
   lbl : TLabel;
   edt : TEdit;
begin
   // dynamisch Komponenten erzeugen und in die Liste packen
   for i := 0 to 10 do
   begin
      lbl := TLabel.Create(FMyList {<==});
      lbl.Caption := Format('Label %d',[i]);
      lbl.Top := i * 15;
      lbl.Left := i * 9;
      lbl.Parent := Self;
   end;

   for i := 0 to 10 do
   begin
      edt := TEdit.Create(FMyList);
      edt.Text := Format('Edit %d',[i]);
      edt.Top := i * 15;
      edt.Left := 300 - i * 20;
      edt.Parent := Self;
   end;

end;

procedure TForm1.ButtonControlsLoeschenClick(Sender: TObject);
begin
   // alle Komponenten in der Liste zerstören
   FMyList.DestroyComponents;
end;
Auch die Typsicherheit lässt sich ganz einfach durch Ableiten von TComponent herstellen.
Bei Interesse kann ich das zeigen.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.018 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: Object dynamisch in einem Array erzeufen

  Alt 13. Okt 2010, 15:26
Es gibt btw. auch noch TComponentList.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

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 01:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf