Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi zugriffsverletzung bei aufruf von destroy (https://www.delphipraxis.net/69887-zugriffsverletzung-bei-aufruf-von-destroy.html)

sancho1980 21. Mai 2006 21:48


zugriffsverletzung bei aufruf von destroy
 
hallo

ich habe folgendes problem:

habe eine mdi-anwendung mit mehreren formularen, wobei ein der formulare der owner von allen anderen formularen ist.
jetz wollte ich erreichen, dass wenn irgendeins der formulare geschlossen wird, alle anderen auch geschlossen werden, also hab ich in die procedure zum onclose-ereignis der einzelnen formulare reingeschrieben:

Delphi-Quellcode:
self.Owner.Destroy()
da schließt sich dann zwar alles so wie ich will, aber leider bekomm ich da auch immer gleich so eine hässliche meldung von wegen "zugriffsverletzung"...was mach ich da falsch?

danke,

martin

Zacherl 21. Mai 2006 22:00

Re: zugriffsverletzung bei aufruf von destroy
 
Warscheinlich ist beim ersten Fenster der Owner undefiniert. Einfach mal mit try .. except .. end abzufangen versuchen.

Florian

Luckie 21. Mai 2006 22:04

Re: zugriffsverletzung bei aufruf von destroy
 
Oder einfach mal die Delphi Hilfe lesen:
Zitat:

Do not call Destroy directly. Call Free instead. Free verifies that the object reference is not nil before calling Destroy.

sancho1980 21. Mai 2006 22:15

Re: zugriffsverletzung bei aufruf von destroy
 
ok, hab ich probiert

das ändert leider auch nichts :|

SirThornberry 21. Mai 2006 22:23

Re: zugriffsverletzung bei aufruf von destroy
 
hast du mal haltepunkte gesetzt und/oder durchgestept bei welchen Befehlen im Destroy die AV kommt?

Zacherl 21. Mai 2006 22:24

Re: zugriffsverletzung bei aufruf von destroy
 
Alternativ zum Free aus Lukies Beitrag:

Delphi-Quellcode:
if Self.Owner <> nil then
  Self.Owner.Destroy;

sancho1980 21. Mai 2006 22:45

Re: zugriffsverletzung bei aufruf von destroy
 
Zitat:

Zitat von SirThornberry
hast du mal haltepunkte gesetzt und/oder durchgestept bei welchen Befehlen im Destroy die AV kommt?

mal ne dumme frage: da müsst ich ja die unit aufmachen, wo das destroy drinsteht...wie find ich n die?

marabu 22. Mai 2006 05:02

Re: zugriffsverletzung bei aufruf von destroy
 
Hallo Martin,

normalerweise ist die Application der Owner, aber egal. Am Beispiel des Templates aus dem Objekt Repository geht es so:

Delphi-Quellcode:
procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  with Application do
    if not Terminated then
      Terminate;
end;
Grüße vom marabu

sancho1980 22. Mai 2006 10:24

Re: zugriffsverletzung bei aufruf von destroy
 
Zitat:

Zitat von marabu
normalerweise ist die Application der Owner, aber egal.

Das geht bei mir leider nicht, weil ich meine Anwendung folgendermaßen gestaltet habe: öffnet der user eine datei, dann wird EIN formular erzeugt (sozusagen das hauptformular für diese eine datei die grad geöffnet wird), welches wiederum mehre andere dazugehörige formulare erzeugt (denen es sich selbst als owner übergibt). es können aber trotzdem mehrere dateien geöffnet sein, was dann heißt, dass sich natürlich pro geöffnetem file die anzahl der fenster verdoppelt. wenn jetzt EIN formular vom user geschlossen wird, will ich, dass ALLE diejenigen formulare zerstört werden, die auch mit der gleichen dateiöffnung zusammenhängen; deswegen hab ich das über den owner gemacht...


grüße,

martin

marabu 22. Mai 2006 10:56

Re: zugriffsverletzung bei aufruf von destroy
 
Ohne MDI-Formulare geht es so:

Delphi-Quellcode:
procedure TParentForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Release;
end;

procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  with Owner as TForm do
    PostMessage(Handle, WM_CLOSE, 0, 0);
end;
marabu

sancho1980 22. Mai 2006 11:45

Re: zugriffsverletzung bei aufruf von destroy
 
danke
wo steht denn das alles?
allerdingst geht es immer noch nicht...hab nämlich vergessen zu erwähnen, dass owner gar kein tform ist, sonder ein tdatamodule :oops:

marabu 22. Mai 2006 12:39

Re: zugriffsverletzung bei aufruf von destroy
 
Wenn ein Datenmodul Owner der ChildForms ist, dann geht das hier:

Delphi-Quellcode:
procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  with Owner as TDataModule do
    if Tag = 0 then
    begin
      Tag := 1;
      Free;
    end else Action := caFree;
end;
marabu

sancho1980 22. Mai 2006 13:19

Re: zugriffsverletzung bei aufruf von destroy
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von marabu
Wenn ein Datenmodul Owner der ChildForms ist, dann geht das hier:

hat's leider auch nicht gebracht :?
aber ich habe mal das Projekt hochgeladen.
die anwendung geht eigentlich nur, wenn man firebird 1.5 installiert hat, aber ich hab mal den entsprechenden code zum öffnen der datenbank weggemacht..also einfach mal auf datei-öffnen-wörterbuch gehen und dann die beigefügte empty.fdb öffnen..darauf öffnen sich 2 formulare..wenn ihr eins der beiden formulare schließt, kommt die meldung von der ich rede...vllt weiß ja einer von euch weiter...
gruß und danke,
martin

marabu 22. Mai 2006 13:32

Re: zugriffsverletzung bei aufruf von destroy
 
Was heißt geht nicht? Kannst du es nicht kompilieren? Gibt es einen Laufzeitfehler?
Wo in deinem Projekt steckt der Code, der ein Datenmodul zum Owner einer Form macht?

marabu

sancho1980 22. Mai 2006 13:35

Re: zugriffsverletzung bei aufruf von destroy
 
doch kompilieren und ausführen geht
aber mach doch mal genau das was ich vorhin meinte:

starte das programm und klick auf

datei->öffnen->wörterbuch (die paar meldungen die da kommen, einfach ignorieren)

dann sollten sich bei dir 2 mdi-childs öffnen

und jetzt schließe mal eins der beiden fenster!

marabu 22. Mai 2006 13:43

Re: zugriffsverletzung bei aufruf von destroy
 
Martin, das geht nicht. Dein Projekt kann ich auf meiner Maschine nicht kompilieren, da du Units einbindest, die bei mir nicht existieren.

Aber unabhängig davon - beim klick auf Wörterbuch soll ein Datenmodul erzeugt werden. Dieses Datenmodul hat keinen event handler für OnCreate() und deshalb können auch keine 2 ChildForms entstehen - oder?

Hast du dein eigenes Demo-Projekt mal in einem eigenen Verzeichnis entpackt und kompiliert?

marabu

sancho1980 22. Mai 2006 14:14

Re: zugriffsverletzung bei aufruf von destroy
 
Liste der Anhänge anzeigen (Anzahl: 1)
jetz merk ich grad
das kann ja bei euch gar nicht funzen, da war ein dateiverweis falsch
jetz nochmal
also bitte nochmal:

datei->öffnen->wörterbuch (die paar meldungen die da kommen, einfach ignorieren)

dann sollten sich bei dir 2 mdi-childs öffnen

und jetzt schließe mal eins der beiden fenster!

sorry deswegen nochmal

gruß


martin

marabu 22. Mai 2006 15:09

Re: zugriffsverletzung bei aufruf von destroy
 
Hallo Martin,

so geht es jetzt:

Delphi-Quellcode:
procedure TLitForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  with Owner as TDataModule do
  begin
    RemoveComponent(self);
    Free;
  end;
  Action := caFree;
end;
marabu

sancho1980 22. Mai 2006 15:56

Re: zugriffsverletzung bei aufruf von destroy
 
ah, jetzt klappt das...
darf ich mal fragen wie du drauf gekommen bist?

außerdem wundert mich folgendes: wenn ich die komponente noch erst selbst aus der komponentenliste entfernen muss, warum muss ich dann nicht vorher auch noch alle anderen komponenten aus der liste entfernen, sondern nur das formular, bei dem onclose aufgerufen wurde?

hab mal ein bisschen rumgespielt und das

Delphi-Quellcode:
RemoveComponent(self);
von dir entfernt und dafür einen ondestroy-handler für das datenmodul reingeschrieben, das folgendes macht:

Delphi-Quellcode:
procedure TDataModule1.DataModuleDestroy(Sender: TObject);
begin
  while (self.ComponentCount > 0) do
    begin
      self.RemoveComponent(self.Components[0]);
    end;
end;
verhält sich aber sehr eigenartig, weil da nur das aufrufende formular, nicht aber das andere geschlossen wird...

[edit]ach ich verstehe: beim aufruf von free für den owner wird automatisch close() für alle anderen formulare ausgeführt, was diese komponenten auch wieder verschwinden lässt, oder?..trotzdem meine frage aus zeile 2 (s.o. in diesem post): darf ich mal fragen wie du drauf gekommen bist?[/edit]

marabu 22. Mai 2006 16:32

Re: zugriffsverletzung bei aufruf von destroy
 
Lieber Martin,

ich programmiere seit etwa 30 Jahren. Ich komme nicht auf etwas - ich erinnere mich nur. Manchmal besser, manchmal schlechter. In letzter Zeit immer schlechter.

Grüße vom marabu


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