Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi eigene Klasse; Constructor inkl. TImage (https://www.delphipraxis.net/152435-eigene-klasse%3B-constructor-inkl-timage.html)

Deinhaus 22. Jun 2010 21:56

eigene Klasse; Constructor inkl. TImage
 
Hallo,

ich habe eine Klasse, die ich jetzt weiterentwickeln will, damit ich in den Prozeduren oder Funktionen das TImage nicht immer gesondert "createn" muss.
Allerdings bekomme ich immer eine Fehlermeldung und mir fällt nix mehr ein.

z.B. bei Create(self): [DCC Fehler] enemy.pas(25): E2010 Inkompatible Typen: 'TComponent' und 'TEnemy'
z.B. bei Create(TEnemy): [DCC Fehler] enemy.pas(25): E2010 Inkompatible Typen: 'TComponent' und 'Class reference'

Die Klasse:
Delphi-Quellcode:
unit enemy;

interface

uses ExtCtrls;

 Type TEnemy = class
      private

      public
        name : string;
        path : string;
        size : integer;
        priority : double;
        image : TImage;
        constructor Create;
    end;

    TEnemyArray = array of TEnemy;

implementation

Constructor TEnemy.Create;
begin
   image := image.Create(????);
end;

end.
Da wo die Fragezeichen stehen habe ich schon alles mögliche ausprobiert (self) (TImage) (TEnemy) (TCompontent(TImage))

Kann mir vielleicht jemand nen Tipp geben, mit dem ich weiter basteln und testen kann?

Gruß
Daniel

Bernhard Geyer 22. Jun 2010 22:03

AW: eigene Klasse; Constructor inkl. TImage
 
Du musst für TEnemy die passende Basisklasse verwenden:

Delphi-Quellcode:
 Type TEnemy = class(TComponent)
Und realisiere image : TImage als read-only-property um klar zu machen das dieses nicht von aussen gesetzt werden kann.

Deinhaus 22. Jun 2010 22:50

AW: eigene Klasse; Constructor inkl. TImage
 
Hm.. hab das Gefühl, dass ich nen Schritt weiter bin, aber so ganz rund läuft das noch nicht.

Hier nochmal die Klasse:
Delphi-Quellcode:
unit enemy;

interface

uses ExtCtrls,Classes;

 Type TEnemy = class(TComponent)
      private

      public
        enemyimage : TImage;
        enemyname : string;
        enemypath : string;
        enemysize : integer;
        enemypriority : double;

        constructor Create();
    end;

    TEnemyArray = array of TEnemy;

implementation

Constructor TEnemy.Create;
begin
   enemyimage := enemyimage.Create(self);
   //enemyimage.Left := 400;
   //enemyimage.Top := 400;
   //enemyimage.AutoSize := true;
end;
und die Prozedur:
Delphi-Quellcode:

procedure tfrm_main.init_enemyarray();
VAR I : integer ;
begin
  SetLength(EnemyArray,FileListBox1.Count+1);
  try

    for I := 0 to FileListBox1.Count-1 do
    begin
      EnemyArray[I] := TEnemy.Create;
      // So lief es ohne CONSTURCTOR
      //EnemyArray[I].enemyimage := TImage.Create(self);
      EnemyArray[I].enemyname := FileListBox1.Items.Strings[I];
      EnemyArray[I].enemyimage.Picture.Icon.Handle := GetShellIcon(FileListBox1.Directory+'\'+FileListBox1.Items.Strings[I], True, False);
    end;
  except
  on E : Exception do
    begin
      WriteLog(E.Message + ' : ' + IntToStr(I));
      ShowMessage(E.Message + ' : ' + IntToStr(I));
    end;
  end;
end;
Zu dem nicht funktionieren CONSTRUCTOR kommt auch noch, die Frage, ob ich
Delphi-Quellcode:
EnemyArray[I].enemyimage.Picture.Icon.Handle
auch beim Create zuweisen kann ? Also quasi das Handle bei Instanziierung übergeben.

READ-ONLY für das Image und auslesen per GET kommt später :)

Hier noch die Fehlermeldung vom EXCEPT:
"Zugriffsverletzung bei Adresse 004BE9EB in Modul 'ADMINV.exe'. Lesen von Adresse 00000000"

Ich vermute jetzt mal, dass das Objekt nicht instanziiert ist und nicht gefunden wird.

Vielen Dank schon mal für die Unterstützung

Gruß
Daniel

Deinhaus 22. Jun 2010 23:42

AW: eigene Klasse; Constructor inkl. TImage
 
Habs gelöst !!

Klasse:
Delphi-Quellcode:
unit enemy;

interface

uses ExtCtrls,Classes,Forms,Windows;

 Type TEnemy = class(TComponent)
      private
        enemyimage : TImage;
        enemyname : string;
      public
        enemypath : string;
        enemysize : integer;
        enemypriority : double;
        constructor Create(AParent: TForm; EName: string; IHandle : HICON);
    end;

    TEnemyArray = array of TEnemy;

implementation

Constructor TEnemy.Create(AParent: TForm; EName: string; IHandle : HICON);
begin
   enemyimage := TImage.Create(AParent);
   with enemyimage do
   begin
    Parent := AParent;
    Left := 400;
    Top := 400;
    AutoSize := true;
    Picture.Icon.Handle := IHANDLE;
    enemyname := EName;
   end;
end;

end.
Procedure:
Delphi-Quellcode:
procedure tfrm_main.init_enemyarray();
VAR I : integer ;
begin
  SetLength(EnemyArray,FileListBox1.Count+1);
  try

    for I := 0 to FileListBox1.Count-1 do
    begin
      EnemyArray[I] := TEnemy.Create(frm_main,FileListBox1.Items.Strings[I],GetShellIcon(FileListBox1.Directory+'\'+FileListBox1.Items.Strings[I], True, False));
    end;
  except
  on E : Exception do
    begin
      WriteLog(E.Message + ' : ' + IntToStr(I));
      ShowMessage(E.Message + ' : ' + IntToStr(I));
    end;
  end;
end;
Gruß
Daniel

DeddyH 23. Jun 2010 08:58

AW: eigene Klasse; Constructor inkl. TImage
 
Damit verbirgst Du aber den Konstruktor von TComponent, das sollte auch eine entsprechende Warnung geben. Und soll das Image von außen komplett unsichtbar sein? Ansonsten würde ich eine ReadOnly-Property einführen.

mkinzler 23. Jun 2010 09:02

AW: eigene Klasse; Constructor inkl. TImage
 
Also am Anfang des Konstruktor einfach den der Superklasse aufrufen

Delphi-Quellcode:
inherited Create( AParent);

DeddyH 23. Jun 2010 09:10

AW: eigene Klasse; Constructor inkl. TImage
 
Und als Owner für das TImage würde ich nicht AParent angeben, sondern entweder self oder nil. Im letzteren Fall muss man das TImage dann aber im Destruktor händisch freigeben.

Deinhaus 23. Jun 2010 12:20

AW: eigene Klasse; Constructor inkl. TImage
 
Also ungefär so !?

Klasse TEnemy:
Delphi-Quellcode:
unit enemy;

interface

uses ExtCtrls,Classes,Forms,Windows;

 Type TEnemy = class(TComponent)
      private
        enemyimage : TImage;
        enemyname : string;
        enemypath : string;
        enemysize : integer;
        enemypriority : double;
      public
        constructor Create(AParent: TForm; EPath : string; EName: string; ESize: Integer; IHandle : HICON);
        destructor Destroy;override;
        property enimage : TImage read enemyimage;
        property enname : string read enemyname write enemyname;
        property enpath : string read enemypath write enemypath;
        property ensize : integer read enemysize write enemysize;
        property enprior : double read enemypriority write enemypriority;
 end;

    TEnemyArray = array of TEnemy;

implementation

Constructor TEnemy.Create(AParent: TForm; EPath : string; EName: string; ESize: Integer; IHandle : HICON);
begin
  inherited Create(nil);
  enemyimage := TImage.Create(nil);
  with enemyimage do
  begin
    Parent := AParent;
    Left := 400;
    Top := 400;
    AutoSize := true;
    Picture.Icon.Handle := IHANDLE;
    enemyname := EName;
    enemypath := EPath;
    enemysize := ESize;
   end;
end;

destructor TEnemy.Destroy;
begin
  enemyimage.Free;
  inherited;
end;

end.
Das AParent übergebe ich, damit das IMAGE auch auf dem FORM angezeigt wird. Aber die erste Zeile des CONSTRUCTORs verstehe ich nicht.
Delphi-Quellcode:
inherited Create(nil);
AParent, so wie vorher geschrieben geht nicht und self auch nicht. Oder ist das mit NIL so richtig?

DeddyH 23. Jun 2010 12:34

AW: eigene Klasse; Constructor inkl. TImage
 
Was heißt denn "geht nicht"? Kommt eine Fehlermeldung? Wenn ja, welche?

Bummi 23. Jun 2010 12:46

AW: eigene Klasse; Constructor inkl. TImage
 
Delphi-Quellcode:
Constructor TEnemy.Create(AOwner:Tcomponent;AParent: TForm; EPath : string; EName: string; ESize: Integer; IHandle : HICON);
begin
  inherited Create(AOwner);

DeddyH 23. Jun 2010 13:00

AW: eigene Klasse; Constructor inkl. TImage
 
Oder man überschreibt einfach den geerbten Konstruktor und lässt die weiteren Eigenschaften anschließend setzen.

Deinhaus 23. Jun 2010 13:41

AW: eigene Klasse; Constructor inkl. TImage
 
bei
Delphi-Quellcode:
inherited Create(AParent);
kommt "ungültige Zeigeroperation"

bei
Delphi-Quellcode:
inherited Create(Owner);
kommt nix. scheint zu gehen.

Wie ist das
Delphi-Quellcode:
inherited Create(Owner);
zu verstehen?

Ich rufe im Constructor der Klasse den Constructor der Superklasse auf mit dem Parameter das meine Klasse der Besitzer des Constructors ist?

Gruß und Dank

DeddyH 23. Jun 2010 13:43

AW: eigene Klasse; Constructor inkl. TImage
 
Nein, Du rufst den geerbten Konstruktor auf und sagst ihm, wer der Owner Deiner Klasse ist.

xZise 23. Jun 2010 16:46

AW: eigene Klasse; Constructor inkl. TImage
 
Mal eine Frage, warum ist dein TEnemy denn ein Nachfahre von TComponent? Das wurde dir ja nur empfohlen, damit du den TImage was übergeben kannst. Oder übersehe ich da was?

Ansonsten einfach standardmäßig von TObject erben (bzw. "gar nicht" erben was ja implizit von TObject erbt).

Außerdem, würde ich den Konstruktor nicht überschreiben ohne das den Code hinzuweisen (mit override). Das geht aber nur, wenn der Konstruktor gleich bleibt.

Wenn du das stattdessen dennoch in einen Einzeiler machen willst, dann würde ich das so machen:

Delphi-Quellcode:
type
  TBlub = class(TParent)
  private
    f : Integer;
  public
    function Init(foo : Integer) : TBlub;
  end;

function TBlub.Init(foo : Integer) : TBlub;
begin
  f := foo;
  Result := Self;
end;
Statt:
Delphi-Quellcode:
type
  TBlub = class(TParent)
  private
    f : Integer;
  public
    constructor Create(foo : Integer);
  end;

constructor TBlub.Create(foo : Integer);
begin
  inherited Create;
  f := foo;
end;
Das sieht dann besser aus, anstatt den Konstruktor zu überdecken.

MfG
Fabian

Deinhaus 23. Jun 2010 18:02

AW: eigene Klasse; Constructor inkl. TImage
 
Hi,

hm... ich hab das gemacht, weil es vorher irgendwie nicht lief und als ich das dann eingetragen hatte, ging es plötzlich.

Ich habs jetzt rausgenommen und es geht auch. Keine Ahnung, was ich noch gemacht habe in der Zwischenzeit.

Frage: Ist es ok, wenn ich den CONSTRUCTOR einer Klasse alle properties der Klasse einstellen lasse, oder sollte ich das gesondert machen damit der CONSTRUCTOR nicht so voll ist?

Gruß

xZise 23. Jun 2010 19:14

AW: eigene Klasse; Constructor inkl. TImage
 
Moin,
Zitat:

Zitat von Deinhaus (Beitrag 1031134)
[...]Ich habs jetzt rausgenommen und es geht auch. Keine Ahnung, was ich noch gemacht habe in der Zwischenzeit.[...]

Du hast was valides im Konstruktor von TImage übergeben.

MfG
Fabian


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