Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Exception EAccessViolation bei inherited add() (https://www.delphipraxis.net/118574-exception-eaccessviolation-bei-inherited-add.html)

blackdrake 10. Aug 2008 23:38


Exception EAccessViolation bei inherited add()
 
Hallo.

Ich bin gerade dabei, eine VCL zu erweitern. Dabei erhalte ich nun eine EAccessViolation bei folgender Funktion:

Delphi-Quellcode:
function TSortListColumns.Add: TSortListColumn;
begin
  Result := TSortListColumn(inherited Add);
end;
Aufgedröselt kann ich erkennen, dass die Exception scheinbar durch inherited verursacht wird:

Delphi-Quellcode:
function TSortListColumns.Add: TSortListColumn;
var
  tmp: TListColumn;
  tmp2: TSortListColumn;
begin
  tmp := inherited Add; // <-- EXCEPTION (wieso da?)
  tmp2 := TSortListColumn(tmp);
  Result := tmp2;
end;
Der vereinfachte Code, der die zusammenhänge zeigt:

Delphi-Quellcode:
type
  TSortListColumns = class(TListColumns)
    {...}
  public
    function Add: TSortListColumn;
  end;

  TSortListView = class(TListView)
    {...}
  published
    property Columns: TSortListColumns read FSortListColumns write SetSortListColumns;
  end;
Die Exception wird ausgelöst bei dem Programmcode:

Delphi-Quellcode:
var tag_history: TSortListView;

tag_history := TSortListView.Create(TagForm);

{...}

with tag_history.Columns.Add do // <-- Exception
begin
  // ...
end;
Weiß jemand weiter? Ich kann mir absolut nicht vorstellen, was hier falsch sein soll, da ich Add() ja nur vererbe.

Ich kann ein kleines Testprogramm zur Verfügung stellen.

Gruß
blackdrake

mkinzler 11. Aug 2008 06:37

Re: Exception EAccessViolation bei inherited add()
 
Du musst Delphi auch sagen, das die Methode geerbt ist (overload)

marabu 11. Aug 2008 06:56

Re: Exception EAccessViolation bei inherited add()
 
Moin Daniel,

der Aufruf von inherited Add() schlägt wahrscheinlich fehl, weil du implizit im Konstruktor von TSortListView immer noch die Collection ListColumns mit der ItemClass TListColumn erzeugst.

Freundliche Grüße

DeddyH 11. Aug 2008 08:09

Re: Exception EAccessViolation bei inherited add()
 
Zitat:

Zitat von mkinzler
Du musst Delphi auch sagen, das die Methode geerbt ist (overload)

Statt overload override.

marabu 11. Aug 2008 08:16

Re: Exception EAccessViolation bei inherited add()
 
Hallo ihr beiden,

ich würde sagen "weder noch" - es geht hier um die statische Methode Add() der unterliegenden Collection.

Freundliche Grüße

DeddyH 11. Aug 2008 08:21

Re: Exception EAccessViolation bei inherited add()
 
Achso, Du meinst, dass weder die Item- noch die Listenklasse abgeleitet bzw. die Ableitungen im Konstruktor nicht benutzt wurden.

marabu 11. Aug 2008 08:43

Re: Exception EAccessViolation bei inherited add()
 
Moin Detlef,

die gewünschten Ableitungen (TListColumn, TListColumns, TSortListView) wurden ja hergestellt, aber im Konstruktor von TSortListView bleibt die Collection "Columns" die alte:

Delphi-Quellcode:
constructor TCustomListView.Create(AOwner: TComponent);
begin
  // ...
  FListColumns := TListColumns.Create(Self);
  // ...
end;
Leider kennt der Konstruktor der Collection nur seine eigene Item-Klasse:

Delphi-Quellcode:
constructor TListColumns.Create(AOwner: TCustomListView);
begin
  inherited Create(TListColumn);
  FOwner := AOwner;
end;
Es ist immer problematisch, wenn bei einer Ableitung auch noch eingebettete Klassen abgeleitet werden sollen und diese Vorgehensweise vom Designer der Klassenhierarchie nicht vorgesehen wurde. Daniel sollte vielleicht nochmal überlegen, ob sein Ansatz hier der richtige ist. Lässt TD nicht schon class decoration zu?

Freundliche Grüße

DeddyH 11. Aug 2008 08:47

Re: Exception EAccessViolation bei inherited add()
 
Moin Achim,

dann war mein weiterer persönlicher Gedankengang ja gar nicht so verkehrt. Ich hatte mich nämlich gefragt, wie zum Kuckuck man in einer Ableitung die "Originalliste" durch seine eigene ersetzen kann. Durch Vererbung ist diese ja bereits vorhanden, nur dann eben vom falschen Typ.

blackdrake 12. Aug 2008 13:25

Re: Exception EAccessViolation bei inherited add()
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.

Das mit overload funktioniert nicht, da die Originalmethode irgendwie virtuell ist.

Das mit dem Impliziten verstehe ich nicht ganz.

Wäre es möglich, dass ihr meinen Code einmal anschaut und mir Ratschläge gebt? Ich habe eine Beispielprojekt gepostet.

Das hier ist mein erster Versuch, irgendwas mit vererbten Klassen und VCLs zu tun. Ich habe daher in diesem Bereich das Wissen einer Tomate.

Ich habe ziemlich lange gebraucht, bis ich TColumn komplett zu TSortColumn erweitern konnte. Diese Column soll eine zusätzliche Eigenschaft "SortMode" haben (das heißt konvertierung von TColumn zu TSortColumn ist ohne Probleme möglich). Diese zusätzliche Eigenschaft beschreibt, mit welchen Sortieralgorithmus die Spalte beim Sortieren behandelt werden soll.

Es ist mir wichtig, dass ich beim Erweitern dieser VCL etwas lerne und mein Wissen über VCL, die properties und die Vererbungen erweitere.

PS: Ich würde außerdem gerne beim "alten" Delphi-Standard bleiben, sofern das in diesem Falle möglich ist. (Sprich: auf moderne Klassenerweiterungen / helper classes / decoration class / etc. verzichten)

Gruß
blackdrake

DeddyH 12. Aug 2008 13:54

Re: Exception EAccessViolation bei inherited add()
 
In der comctrls.pas von Delphi 5 steht Folgendes:
Zitat:

Delphi-Quellcode:
TCustomListView = class(TWinControl)
  private
    ...
    FListColumns: TListColumns;
    ...
    procedure SetListColumns(Value: TListColumns);
    ...
  protected
    ...
    property Columns: TListColumns read FListColumns write SetListColumns;
    ...
  end;

Da die Deklaration von FListColumns im private-Abschnitt steht, kommst Du da nicht ran, kannst also nicht ohne Weiteres auf Deinen Typ "umbiegen". Sofern Du über die VCL-Sourcen verfügst, bliebe Dir noch die Möglichkeit, die gesamte Kompo von Grund auf aufzubauen, den Originalsource könntest Du als Anhaltspunkt nehmen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:43 Uhr.
Seite 1 von 3  1 23      

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 by Thomas Breitkreuz