Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie arbeite ich mit "Klassen"-Listen (https://www.delphipraxis.net/112620-wie-arbeite-ich-mit-klassen-listen.html)

EccoBravo 24. Apr 2008 15:14


Wie arbeite ich mit "Klassen"-Listen
 
Hallo,

Euer erster Schritt, mir in oop zu helfen war prima.

Nun gleich zu einer exotischen Anwendung von Objekten, und zwas in einer Liste.
Der folgende Code soll die Frage Euch verdeutlichen:


Delphi-Quellcode:
unit EB_Pat_Foto_Unit1;

interface

uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    IniFiles,
    Dialogs, StdCtrls, ExtCtrls, FileCtrl, ShellAPI,
    SDL_ColSel, SDL_Thumbnails, ComCtrls, ShellCtrls;

type
    ...

    TSatz = class(TObject)
        Bild: TImage;
        BildName: string;
        BildNurName: string;
        BildNurPath: string;
        BildNurExt: string;
        FileName: string;
        FileNurName: string;
        FileNurPath: string;
        FileNurExt: string;

        Datum: string;
        Notiz: string;
        Checked: boolean;
    private
        Fgeb: string;
        FPatName: string;
        FID: string;
        FInhalt: string;
        function GetID: string;
        function GetPatName: string;
        function GetGeb: string;
        function GetInhalt: string;
        procedure Setgeb(const Value: string);
        procedure SetID(const Value: string);
        procedure SetPatName(const Value: string);
        procedure SetInhalt(const Value: string);
    public
        property PatName: string read GetPatName write SetPatName;
        property geb: string read Getgeb write Setgeb;
        property ID: string read GetID write SetID;
        property Inhalt: string read GetInhalt write SetInhalt;
    end;

var
    ...

    Satz: array of TSatz;   // dieses wird im Folgenden
                             // Probleme machen

    ...


implementation

uses ... ;

{$R *.dfm}
//..............................................................................

procedure TForm1.FormCreate(Sender: TObject);
var
    i: integer;
    Fehler: Word;
    DatumStr: string;

begin

    ...
    Satz := TSatz.create; // und das mag der Compiler nicht
                           // wegen "array of TSatz"
                           // Instanzendeklaration
    setlength(Satz, 50);
    ...

end;

...
end.
Im Code habe ich das Problem schon markiert.
Von der Klasse TSatz will ich ein dynamisches Array instanzieren
und beim Instanz.Create gibt es Compiler-Mecker.

Wie kann ich dieses Problem wohl am besten lösen?
Gibt es da nicht irgend eine andere Lösung mit Listen oder so ?

Danke für Hilfe

E. B.

mkinzler 24. Apr 2008 15:16

Re: Wie arbeite ich mit "Klassen"-Listen
 
Delphi-Quellcode:
inc(anz);
SetLength( satz, anz);
Satz[anz-1] := TSatz.create; // und das mag der Compiler nicht
                           // wegen "array of TSatz"
                           // Instanzendeklaration

Dunkel 24. Apr 2008 15:29

Re: Wie arbeite ich mit "Klassen"-Listen
 
Delphi-Referenz durchsuchenTObjectList

bluesbear 24. Apr 2008 15:34

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hallo EccoBravo,
mit Listen und so geht das natürlich auch. Guck mal in der Hilfe nach TObjectList. Mein Vorschlag:
In Form1 deklarierst du FSatzListe : TObjectList;
In TForm1.FormCreate erzeugst du dann die Objektinstanz dazu.
Sätze in die Liste einfügen: FSatzListe.Add(TSatz.Create);

P.S.: ich war schon wieder zu langsam :(

Brainshock 24. Apr 2008 16:05

Re: Wie arbeite ich mit "Klassen"-Listen
 
Da es sich nur um eine Klasse (nämlich TSatz) handelt, kann man sogar auf eine TCollection gehen.

Ralf Kaiser 24. Apr 2008 16:11

Re: Wie arbeite ich mit "Klassen"-Listen
 
Zitat:

Zitat von Brainshock
Da es sich nur um eine Klasse (nämlich TSatz) handelt, kann man sogar auf eine TCollection gehen.

Eben nicht. Dann müsste TSatz von TCollectionItem abgeleitet sein. :wink:

EccoBravo 24. Apr 2008 17:41

Re: Wie arbeite ich mit "Klassen"-Listen
 
Wie mache ich das in meinem Falle?

Für TObjectList brauche ich

Delphi-Quellcode:
Uses Contnrs ...
Wenn ich in meinem Code:

Delphi-Quellcode:
unit EB_Pat_Foto_Unit1;

interface

uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    IniFiles,
    Dialogs, StdCtrls, ExtCtrls, FileCtrl, ShellAPI,
    SDL_ColSel, SDL_Thumbnails, ComCtrls, ShellCtrls, Contnrs;

type
    ...

    TSatz = class(TObject)
        Bild: TImage;
        BildName: string;
        BildNurName: string;
        BildNurPath: string;
        BildNurExt: string;
        FileName: string;
        FileNurName: string;
        FileNurPath: string;
        FileNurExt: string;

        Datum: string;
        Notiz: string;
        Checked: boolean;
    private
        Fgeb: string;
        FPatName: string;
        FID: string;
        FInhalt: string;
        function GetID: string;
        function GetPatName: string;
        function GetGeb: string;
        function GetInhalt: string;
        procedure Setgeb(const Value: string);
        procedure SetID(const Value: string);
        procedure SetPatName(const Value: string);
        procedure SetInhalt(const Value: string);
    public
        property PatName: string read GetPatName write SetPatName;
        property geb: string read Getgeb write Setgeb;
        property ID: string read GetID write SetID;
        property Inhalt: string read GetInhalt write SetInhalt;
    end;

var
    ...

    Satz: TSatz;                   // hier beginnen meine
    SatzListe: TObjectList;        // Unsicherheiten    
    ...


implementation

uses ... ;

{$R *.dfm} 
//..............................................................................

procedure TForm1.FormCreate(Sender: TObject);
var
    i: integer;
    Fehler: Word;
    DatumStr: string;

begin

    ...
    SatzListe := TObject.Create;     // hier bin ich
    for i := 0 to maxSatzZahl do     // ebenfalls unsicher
        SatzListe.Add(TAstz.Create); // ...
    ...

end;

...
...

procedure TForm1.E_geborenExit(Sender:TObject);
begin
    Satz[1].geb := E_geboren.Text;   // hier meckert der Compiler E2149 !!!!
end;                                 // schon beim compilieren

...
...

end.
Jetzt könnt Ihr Euch sicherlich vorstellen, wie wenig Ahnung ich von TObjectList habe.

Ich will im Programm über einen IndexInteger auf einzelne Datensätze der Liste zugreifen.

Delphi-Quellcode:
Satz[i] := ...;

... := Satz[j];
Ja, Unwissenheit schützt vor Dummheit nicht,

Vielleicht Könnt Ihr mir da weiterhin helfen

Danke, Grüße ...

E. B.

Pfoto 24. Apr 2008 17:51

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hallo,

um auf die einzelnen Objekte zugreifen zu können,
machst du einfach das hier:

Delphi-Quellcode:
 
  TSatz(Satzliste.Items[1]).Eigenschaft:= 'bla';
TObjectlist gibt standardmäßig auch den Speicher
der Objekte wieder frei.

Edit:
Zitat:

Zitat von EccoBravo
SatzListe := TObject.Create; // hier bin ich
for i := 0 to maxSatzZahl do // ebenfalls unsicher
SatzListe.Add(TAstz.Create); // ...

Du erstellt in deinem Beispiel ein Objekt und
nicht die Objektliste, aber ansonsten ist
die Vorgehensweise richtig.

Gruß
Pfoto

Die Muhkuh 24. Apr 2008 17:54

Re: Wie arbeite ich mit "Klassen"-Listen
 
Dann typisieren wir die Liste noch und können uns das casten sparen ;)

Luckie 25. Apr 2008 08:06

Re: Wie arbeite ich mit "Klassen"-Listen
 
Siehe hier: Container-Klassen in Delphi

EccoBravo 25. Apr 2008 11:46

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hallo Pfoto,

Wie erstelle ich dann eine Objektliste und kein Object?

Danke

E. B.

angos 25. Apr 2008 12:02

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hi,

hoffe das hilft dir.


Delphi-Quellcode:

type
  TMyObject = class(TObject)
  private
    FNAme: String;
  public
    property Name: String read FName write FName;
  end;

type
  TMyObjectList = class(TObjectList)
  private
    function GetItem(ndx: Integer): TMyObject;
    procedure SetItem(ndx: Integer; AValue: TMyObject);
  public
    property items[ndx: Integer]:TMyObject read GetItem write SetItem;
   
  end;
 
 
implementation

function TMyObjectList.GetItem(ndx: Integer): TMyObject;
begin
  Result := TMyObject(inherited items[ndx]);
end;

procedure TMyObjectList.SetItem(ndx: Integer; AValue: TMyObject);
begin
  items[ndx] := AValue;
end;
Mit dem Konstrukt kannst du dann zb sowas machen
Delphi-Quellcode:
procedure irgendwas;
var
 aList: TMyObjectList;
begin
  aList := TMyOBjectList.Create;
  aList.Add(TMyObject.Create);

  aList.items[0].Name := 'Hello World';
end;
Grüße

NickelM 25. Apr 2008 12:13

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hi,

Ich hab das bei meinem Spiel sogemacht

Delphi-Quellcode:
//als erstes von TCollectionItem ableiten
//beispiel von mir
TLager = class(TCollectionItem)
//eigene Eigenschaften
end;

//dann hab ich eine Klasse wo die Variable gespeichert ist
TSchiff = class(TGlFreeForm) //einge klasse von meiner Engien hatt nicht damit zutun
private
FLagerliste : TCollection //kann auch eine Variable sein
published
property Lagerliste : TCollection read FLagerliste write FLagerliste;
end;

//im Creater dann
FLagerliste := TCollection.Create(TLager) //die abgeleitete TCollectionItem Klasse
//dann for-Schleife
for I := 0 to 4 do
with FLagerliste.Add as TLager do //kannst du direkt auf die neue Klasse zugreifen
//sachen, die du verändern willst
So ich hoffe ich habe es richtig verstahnden, was du willst und wenn, dann hoffe ich das es dir hilft.

EccoBravo 25. Apr 2008 14:39

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hallo angos und Danke an alle,

angos,
soweit so gut, compilieren soweit ohne Mecker,
angos, Deine Lösung gefällt mir am besten.

beim Ausführen des Programms kommt dann aber eine Meldung;

Zitat:

Im Project EB_Pat_Foto_Project1.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei der Adresse 00419F9E in Modul EB_Pat_FotoProject1.exe'. 'Lesen von Adresse 00000008' aufgetreten.
Erste Frage:
Ich weiss nicht, was da los ist (Antwort auf diese Frage kann ich wohl nicht erwarten)

Zweite Frage:
Wie kann ich bei Form1.close die Objectliste wieder frei geben?

Also nochmals vielen Dank.
Ihr tragt nicht nur mit Töpfen Licht ins Dunkle.

Grüße

E. B.

Relicted 25. Apr 2008 14:49

Re: Wie arbeite ich mit "Klassen"-Listen
 
ich habe mal kurz mein minitool angeschmissen.

Delphi-Quellcode:
unit SatzList;                                                                
                                                                                       
interface                                                                              
                                                                                       
uses                                                                                  
  Contnrs,                                                                            
  Satz;                                                                      
                                                                                       
type                                                                                  
  TSatzList = class( TObjectList )                                            
  protected                                                                            
    //* Protected functions..                                                          
    function GetItem(Index: Integer): TSatz; reintroduce;                    
    procedure SetItem(Index: Integer; const Value: TSatz); reintroduce;      
  public                                                                              
    //* Constructors.. don't forget to call "inherited"                              
    //constructor Create; overload;                                                    
    //constructor Create(AOwnsObjects: Boolean); overload;                            
                                                                                       
    //* List Functions & Propertys                                                    
    function Add(AObject: TSatz): Integer; reintroduce;                      
    function Extract(Item: TSatz): TSatz; reintroduce;              
    function Remove(AObject: TSatz): Integer; reintroduce;                    
    function IndexOf(AObject: TSatz): Integer; reintroduce;                  
    procedure Insert(Index: Integer; AObject: TSatz); reintroduce;            
    function First: TSatz; reintroduce;                                      
    function Last: TSatz; reintroduce;                                        
                                                                                       
    property Items[Index: Integer]: TSatz read GetItem write SetItem; default;
                                                                                       
    //* Insert your own functions here...                                              
  end;                                                                                
                                                                                       
implementation                                                                        
                                                                                       
{ TSatzList }                                                                 
                                                                                       
function TSatzList.Add(AObject: TSatz): Integer;                    
begin                                                                                  
  result := inherited Add( AObject );                                                  
end;                                                                                  
                                                                                       
function TSatzList.Extract(Item: TSatz): TSatz;            
begin                                                                                  
  result := inherited Extract( Item ) as TSatz;                              
end;                                                                                  
                                                                                       
function TSatzList.First: TSatz;                                    
begin                                                                                  
  result := inherited First as TSatz;                                        
end;                                                                                  
                                                                                       
function TSatzList.GetItem(Index: Integer): TSatz;                  
begin                                                                                  
  result := inherited GetItem( Index ) as TSatz;                              
end;                                                                                  
                                                                                       
function TSatzList.IndexOf(AObject: TSatz): Integer;                
begin                                                                                  
  result := inherited IndexOf( AObject );                                              
end;                                                                                  
                                                                                       
procedure TSatzList.Insert(Index: Integer; AObject: TSatz);          
begin                                                                                  
  inherited Insert(Index,AObject);                                                    
end;                                                                                  
                                                                                       
function TSatzList.Last: TSatz;                                      
begin                                                                                  
  result := inherited Last as TSatz;                                          
end;                                                                                  
                                                                                       
function TSatzList.Remove(AObject: TSatz): Integer;                  
begin                                                                                  
  result := inherited Remove(AObject);                                                
end;                                                                                  
                                                                                       
procedure TSatzList.SetItem(Index: Integer;                                  
  const Value: TSatz);                                                        
begin                                                                                  
  inherited SetItem(Index,Value);                                                      
end;                                                                                  
                                                                                       
end.
That's the way i alway do. eine typisierte TObjectList. Finde ist das einfachste was man machen kann.
habe mir das tool "mal eben" geschrieben weil ich keine lust auf das dauernde ersetzen etc hatte. basisklasse eingeben start drücken fertig werden :-) daher mal schnell die "lösung" bereitstell

gruß
reli

Luckie 25. Apr 2008 14:52

Re: Wie arbeite ich mit "Klassen"-Listen
 
Zitat:

Zitat von Luckie

Das scheint irgendwie jeder zu irgnorieren. :?

Relicted 25. Apr 2008 14:53

Re: Wie arbeite ich mit "Klassen"-Listen
 
Zitat:

Erste Frage:
Ich weiss nicht, was da los ist (Antwort auf diese Frage kann ich wohl nicht erwarten)
entweder ist die liste oder das objekt was du da rein gepackt hast nicht initialisiert worden. oder du greifst auf kA position 4 zu, hast aber nur 4 objekte in der liste (0..3) ohne meine glaskugel komm ich da gerade auch ned weiter.

Zitat:

Zweite Frage:
Wie kann ich bei Form1.close die Objectliste wieder frei geben?
die liste einfach über die variable mit
Delphi-Quellcode:
FreeAndNil( FMeineListe );
freigeben.

gruß
reli


edit: Luckie das is doch oversized :-p *duck*

Luckie 25. Apr 2008 15:01

Re: Wie arbeite ich mit "Klassen"-Listen
 
Das ist nicht oversized, das ist genau das, was ihr heir die ganze zeit zu erklären versucht. ;)

Relicted 25. Apr 2008 15:08

Re: Wie arbeite ich mit "Klassen"-Listen
 
ah sorry. ja ich hab dir gerade unrecht getan. ich hatte noch im hinterkopf dass hier jemand an einem "generics for win32" ähnlichem gerüst gearbeitet hat. oder es jedenfalls hier diskutiert wurde. und als ich dann kurz den thread überflogen habe sah ich den D.NET ansatz von elvis und ich dachte mir: "generics sind genau das richtige was ein anfänger braucht - bei uns in der firma hatten bei der schulung von bernd ua schon einige alteingesessene leute probleme mit den dingern" und äußerte mich deshalb mit oversized. aber du hast recht. das ist genau was er braucht und wie immer auf die gute luckie art erklärt.

EccoBravo 25. Apr 2008 16:45

Re: Wie arbeite ich mit "Klassen"-Listen
 
Prima allerseits,

es funktioniert,
Danke für alle für die Hilfe.

Der Vorschlag von angos war mir am sympatischten,
Den Fehler habe ich übringens auch gefunden, die Initialisierung der SatzList:TSatzList in der Form.Create war am Emde der Methode und mußte an den Anfang der Methode, weil in dieser schon gebraucht.

Nun habe ich die Vorzüge des RAD2007 Together voll genossen.
Nachdem ich das alles fertig hatte habe ich mit einem Federstreich zuerst die Klasse TSatz in eine neue Unit ausgelagert und dann auch die ganze Klasse TSatzList.
Nun ist das eigentliche Programm ein kleiner Vers geworden und läßt sich prima pflegen.

Nun bin ich zufrieden und gehe nach haus.

Euch allen ein schönes Wochenende

E. B.

Luckie 25. Apr 2008 23:05

Re: Wie arbeite ich mit "Klassen"-Listen
 
Zitat:

Zitat von Relicted
und wie immer auf die gute luckie art erklärt.

Besten Dank für das Kompliment. :P

angos 25. Apr 2008 23:10

Re: Wie arbeite ich mit "Klassen"-Listen
 
Hi und danke für die Blumen,

wobei ich noch sagen muss: der Vorschlag von Relicted ist quasi das gleiche wie meines, nur direkt schon mit erweiterter Funktionalität. Nimms auf jedenfall mal mit, wenn du dich grad durch die OOP kämpfst ;)

Da es jetzt schon spät (oder früh, je nach Sichtweise) ist, schau ich mir Luckies Link erst morgen an und kann dazu grad nichts sagen. Anschauen solltest du dir das auf jedenfall auch, weil von Luckie eigentlich viel Brauchbares kommt was auch gut erklärt ist.


Gruß und Gute Nacht

PS: Warum bin ich eigentlich noch nicht auf die Idee gekommen, ein Tool zur schnellen Erzeugung von Klassenstrukturen zu bauen :?

Todo.Add(Daten_Im_Kopf);

[Edit] so jetzt reichts auch mit dem Luckie-Schleimen der Comunity :stupid: :angel:


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