![]() |
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:
Aufgedröselt kann ich erkennen, dass die Exception scheinbar durch inherited verursacht wird:
function TSortListColumns.Add: TSortListColumn;
begin Result := TSortListColumn(inherited Add); end;
Delphi-Quellcode:
Der vereinfachte Code, der die zusammenhänge zeigt:
function TSortListColumns.Add: TSortListColumn;
var tmp: TListColumn; tmp2: TSortListColumn; begin tmp := inherited Add; // <-- EXCEPTION (wieso da?) tmp2 := TSortListColumn(tmp); Result := tmp2; end;
Delphi-Quellcode:
Die Exception wird ausgelöst bei dem Programmcode:
type
TSortListColumns = class(TListColumns) {...} public function Add: TSortListColumn; end; TSortListView = class(TListView) {...} published property Columns: TSortListColumns read FSortListColumns write SetSortListColumns; end;
Delphi-Quellcode:
Weiß jemand weiter? Ich kann mir absolut nicht vorstellen, was hier falsch sein soll, da ich Add() ja nur vererbe.
var tag_history: TSortListView;
tag_history := TSortListView.Create(TagForm); {...} with tag_history.Columns.Add do // <-- Exception begin // ... end; Ich kann ein kleines Testprogramm zur Verfügung stellen. Gruß blackdrake |
Re: Exception EAccessViolation bei inherited add()
Du musst Delphi auch sagen, das die Methode geerbt ist (overload)
|
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 |
Re: Exception EAccessViolation bei inherited add()
Zitat:
|
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 |
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.
|
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:
Leider kennt der Konstruktor der Collection nur seine eigene Item-Klasse:
constructor TCustomListView.Create(AOwner: TComponent);
begin // ... FListColumns := TListColumns.Create(Self); // ... end;
Delphi-Quellcode:
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?
constructor TListColumns.Create(AOwner: TCustomListView);
begin inherited Create(TListColumn); FOwner := AOwner; end; Freundliche Grüße |
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. |
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 |
Re: Exception EAccessViolation bei inherited add()
In der comctrls.pas von Delphi 5 steht Folgendes:
Zitat:
|
Re: Exception EAccessViolation bei inherited add()
Hallo.
Man kann doch keine Grund-VCL verändern. Dann würde die VCL ja ohne diese Modifikation nicht laufen. Ist es so abnormal, eine TColumn durch Ableiten erweitern zu wollen? Kann ich denn nicht einfach relevante Stellen überschreiben, die auf dieses private-Symbol zugreifen? Ich verstehe außerdem das Problem nicht so ganz: Wenn ich Funktionen wie z.B. Add() überschreibe, den Vorgänger mit inherited aufrufe und dann innerhalb meiner Funktion eine Konvertierung TColumn -> TSortColumn durchführe, müsste doch alles klaro sein, oder? Wie sollte ich jetzt vorgehen? Bitte um Vorschläge. Gruß blackdrake |
Re: Exception EAccessViolation bei inherited add()
Wer hat denn gesagt, dass Du die VCL ändern sollst?
|
Re: Exception EAccessViolation bei inherited add()
Entschuldige, ich habe da etwas falsch verstanden. Du meinst also, ich solle alle Stellen überschreiben, die mit TListColumns verbunden sind? Wäre dann die EAccessViolation weg, oder ist das eine Vermutung?
|
Re: Exception EAccessViolation bei inherited add()
ADD:
Ich habe gerade bemerkt, dass ich diese Dinger bereits überschrieben habe:
Delphi-Quellcode:
TSortListView = class(TListView)
private FSortListColumns: TSortListColumns; procedure SetSortListColumns(Value: TSortListColumns); ... published property Columns: TSortListColumns read FSortListColumns write SetSortListColumns; ... end; |
Re: Exception EAccessViolation bei inherited add()
Was ich gemeint hatte war, den gesamten Source von TCustomListview zu kopieren, in dieser Kopie die relevanten Stellen zu ändern und die gewünschten Funktionalitäten zu ergänzen und das ganze dann als eigene Klasse zu speichern. Ist zwar viel Arbeit, aber eine saubere Lösung.
[edit] TCustomListview heißt das :oops: [/edit] |
Re: Exception EAccessViolation bei inherited add()
Hallo.
Reicht es denn nicht, die relevanten Stellen (die mit Column zu tun haben) in der Ableitung neu zu definieren? Ich habe ja wie bereits erwähnt die wichtigen Funktionen wie SetListColumns(), aber auch TLVColumnClickEvent ersetzt und neu definiert. Das ist doch der Sinn der Ableitung. Ich wüsste jetzt nicht genau, was ich noch neu definieren sollte, da ich alle Column-Bezogenen Dinge bereits neu definiert / überschrieben habe (anders wäre der Code unkompilierbar gewesen). Weißt du, wieso es zu der AccessViolation kommt? Für mich ist das immer noch ein Rätsel, da ich keinen Fehler und keine Ungereimtheit sehen kann. Gruß blackdrake |
Re: Exception EAccessViolation bei inherited add()
Schau Dir nochmal marabus Beitrag #7 an. Das kannst Du nicht ändern, da es als private deklariert ist.
|
Re: Exception EAccessViolation bei inherited add()
Ist es denn nicht egal, wenn die untergeordnete Klasse ihr FListColumns vom Typ TListColumns hat?
Meine Klasse hat schließlich ihr eigenes FSortListColumns vom Typ TSortListColumns. Wenn meine Klasse diese Eigenschaft selbstständig handelt, dann ist es doch egal, wenn die untergeordneten Klassen mit dem nicht-erweiterten Typ TListColumns arbeiten, oder? Verstehst du meinen Gedankengang? (Ist bestimmt absoluter Müll, was ich da denke) Entschuldige bitte mein großes Unwissen. Wie ich bereits schrieb, habe ich sehr wenig Ahnung von Vererbung und VCL... |
Re: Exception EAccessViolation bei inherited add()
Ach du meinst, Du lässt die Originalliste einfach stehen und biegst die Property Items um? Das könnte evtl. sogar klappen :gruebel:
[edit] Columns, nicht Items (ich bin so verstreut heute :stupid:) [/edit] |
Re: Exception EAccessViolation bei inherited add()
Irgendwelche Ergebnisse erzielen können? Bei mir negativ. Ich habe lediglich noch herausgefunden, dass die EXE nach der EAccessViolation sich noch ausführen lässt. Aber den Grund habe ich immer noch nicht rausbekommen :(
|
Re: Exception EAccessViolation bei inherited add()
Ich kämpfe im Moment "an allen Fronten", hab daher leider keine Luft, um mir das im Detail anzusehen. Evtl. morgen :|
|
Re: Exception EAccessViolation bei inherited add()
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.
Ich habe bei meinem Demoprojekt die ganzen Schritte von OnCreate() in ein Button-Click-Ereignis geschoben (soll später in OnShow, mit Aufruf von Loaded). Bei OnCreate ist die ImageList ja noch gar nicht geladen, weswegen es das Loaded() Problem gab (das du für mich gefunden hast). Ich erhalte bei folgender Stelle nun eine Meldung "Listenindex überschreitet Maximum 0":
Delphi-Quellcode:
Das Seltsame:
with tag_history.Columns.Add do
begin Caption := '1'; // EXCEPTION Width := (tag_history.Width - 20) div 3 * 2; end;
Delphi-Quellcode:
Der Debugger sagt bei F7 nicht, dass es bei "inherited Add" weiter (in die "tiefe") geht!!
function TSortListColumns.Add: TSortListColumn;
begin Result := TSortListColumn(inherited Add); end; Normalerweise sollte er bei
Delphi-Quellcode:
weitermachen! Hier wird der Haltepunkt aber niemals erreicht.
{ ComCtrls }
function TListColumns.Add: TListColumn; begin Result := TListColumn(inherited Add); UpdateCols; end; Auch die noch weiter oben liegende Weiterleitung
Delphi-Quellcode:
wird niemals erreicht...
{ Classes }
function TCollection.Add: TCollectionItem; begin Result := FItemClass.Create(Self); Added(Result); end; Komisch. TSortListColumns ist das Kind von TListColumns, also müsste doch die inherited-Variante bei TListColumns.Add() anknüpfen, oder nicht??? Irgendeine Idee? Gruß Daniel Marschall blackdrake |
Re: Exception EAccessViolation bei inherited add()
Kann mir denn niemand helfen? Wieso ruft inherited nicht die höhere Instanz auf? Ich habe sogar in die ComCtrls.pas eine showmessage() eingebaut, um ganz sicher zu gehen, dass sich der Debugger nicht geirrt hat. Der Punkt wird tatsächlich nicht erreicht.
Ich weiß nicht, ob das komplette Neuschreiben der Klasse überhaupt notwendig ist, da man es mit der Ableitung eigentlich prima hinbekommen könnte. (Schließlich macht es Borland meist genau so, z.B. mit den TCollectionItems, die einfach durch Ableiten erweitert werden) |
Re: Exception EAccessViolation bei inherited add()
Delphi-Quellcode:
Das kann doch nicht sein. Das Vererbungsmodell von Delphi funktioniert hier einfach nicht! Die Methode "Add" ist nicht als virtuell definiert, so dass man sie nicht mit override überschreiben kann.
function TSortListColumns.Add: TSortListColumn;
var x: TListColumn; y: TSortListColumn; begin x := inherited Add; // NACH DIESEM PUNKT IST MIT F7 DIE PROZEDUR ZUENDE! // DER DEBUGGER GEHT NICHT IN DIE TIEFE y := TSortListColumn(x); // DIESER PUNKT WIRD NIEMALS ERREICHT Result := y; // DIESER PUNKT WIRD NIEMALS ERREICHT //Result := TSortListColumn(inherited Add); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:02 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 by Thomas Breitkreuz