Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Fehler beim beenden durch FormDestroy (https://www.delphipraxis.net/8152-fehler-beim-beenden-durch-formdestroy.html)

NormanSteinmetz 29. Aug 2003 13:42


Fehler beim beenden durch FormDestroy
 
Hallo leute,

hoffentlich bin ich hier richtig mit meinem Thread.
Ich bin dabei mir einen Player zu schreiben, der nicht nur über ein Formular verfügt. Beim starten ist nur der player sichtbar alle anderen sind zwar gestartet aber nicht sichtbar. Ist meine Playlist geladen kann ich auch drauf zugreifen das, es funzt also alles eigentlich so wie es soll bis auf das beim beenden des Players noch einstellungen gespeichert werden sollen also habe ich noch die Funktion FormDestroy eingefügt so das die Einstellungen gespeichert werde auch wenn das Programm z.B. durchs runterfahren beendet wird. Genau da fängt mein Problem an, wenn ich das Programm dann beenden will kommt es zu einer Zugriffsverletzung aber auch nur wenn ich auf eine der anderen Fenster zugreife. Lasse ich die Funktion FormDestroy weg kann ich den player beenden ohne das ein Fehler auftaucht. Wo habe ich etwas vergessen? Muss ich in den anderen Formularen auch eine FormDestroy einfügen?

Kann mir da jemand helfen?

MFG
Norman

Tpercon 29. Aug 2003 13:46

Re: Fehler beim beenden durch FormDestroy
 
Erstmal Herzlich Willkommen im DP.

Dann poste mal bitte deinen Code vom OnDestroy Ereignis.

NormanSteinmetz 29. Aug 2003 14:17

Re: Fehler beim beenden durch FormDestroy
 
hallo,

das ist der code ist nichts besonderes wie man sehen kann, ehrlich gesagt habe ich hiermit noch nicht so viel erfahrung gemacht bin ins netz und habe nach etwas gesucht was das Prog abfängt wenn es beendet wird. Der Satz soll mir nur zeigen das die Prozedur aufgerufen wird.
Der Code zum schreiben der config.ini muss ja auch noch rein aber erstmal muss geregelt sein das ich das Programm ja beenden kann ohne Fehler.

Delphi-Quellcode:
// Freilassen der rescourcen wenn das programm beendet wird
procedure Tform_player.FormDestroy(sender: TObject);
begin
application.MessageBox('Das Programm wird beendet', 'Beenden', MB_OK + MB_ICONQUESTION);
BASS_FX_FREE;
BASS_FREE;
end;
MFG
Norman

[edit=Daniel B]Delphi-Tags eingefügt. Mfg, Daniel B[/edit]

Tpercon 29. Aug 2003 14:21

Re: Fehler beim beenden durch FormDestroy
 
Wenn du die Zeilen
Delphi-Quellcode:
BASS_FX_FREE;
BASS_FREE;
auskommentierst, läuft es bestimmt ohne Probleme, oder?

Also muß es an einer der beiden Prozeduren liegen (also, her mit dem Code:) )!

NormanSteinmetz 29. Aug 2003 15:00

Re: Fehler beim beenden durch FormDestroy
 
Liste der Anhänge anzeigen (Anzahl: 1)
hallo,

ich habe BASS_Free und BASS_FX_Free raus genommen aber der Fehler bleibt leider, trotzdem habe ich den code der BASS beigefügt allerdings nur als anhang da sie doch recht gross sind. Die sind die Grundlagen der BASS.DLL für die audiowiedergabe, ich schätze das Dir das bekannt vorkommt.

Wie gesagt es trit nur auf wenn ich ein andere Formular benutze sonst beendet er ihn normal. die anderen Formen haben keine Destroy Prozedur.

MFG
Norman

Tpercon 29. Aug 2003 15:07

Re: Fehler beim beenden durch FormDestroy
 
Der Fehler liegt also definitiv nicht im OnDestroy Ereignis.
Wie wird denn codemäßig ein Formular bei dir aufgerufen? Werden sie automatisch erzeugt oder versuchst du sie dynamisch zu erzeugen?

NormanSteinmetz 29. Aug 2003 15:20

Re: Fehler beim beenden durch FormDestroy
 
Hallo,

bei mir werden alle automaitsch erzeugt, das gibt zumindest die Project Datei an. Wie man ein Formular dynamisch erzeugt. so viel erfahrung habe ich noch nicht mit Delphi wenn ich ehrlich bin.

Ich vermute mal es liegt daran das die anderen Formulare im Hintergrund noch aktiv sind kann das sein?

MFG
Norman

Memo 29. Aug 2003 16:57

Re: Fehler beim beenden durch FormDestroy
 
Zitat:

Zitat von NormanSteinmetz
Ich vermute mal es liegt daran das die anderen Formulare im Hintergrund noch aktiv sind kann das sein?

Ich vermute mal das sie es ebend nicht mehr sind.

Du hast ein einmal geschrieben, das es ohne Free geht und kurze Zeit später schreibst du, das es ohne Free auch nicht mehr geht. Wie nun?

NormanSteinmetz 29. Aug 2003 17:24

Re: Fehler beim beenden durch FormDestroy
 
hallo,

nein ich meine das wenn ich Free weg lasse bleibt der OnDestroy Fehler. Es liegt nicht daran. Der Fehler taucht nur auf wenn ich auf eines der anderen Formulare zugreife.

Wenn ich also versuche von dem Hauptformular aus einen Wert aus einer ListBox im zweiten Formular zu bekommen klappt es und solange das Programm am laufen ist geht auch alles wunderbar. erst wenn ich es beende und die Destroy Prozedur anfängt kommt die Zugriffsverletzung.

Beende ich das programm allerdings ohne das ich auf ein anderes Formular zugegriffen habe bekomme ich keine Fehlermeldung und er beendet das Programm vorschriftsgemäss.

Es ist auch egal ob ich Free in der Prozedur habe oder nicht also daran liegt es in keinem fall.

OnDestroy liegt nur auf dem Hauptformular.
Der Fehler beginnt sobald die Prozedur aufgerufen wird.

Ich hoffe ich habe jetzt nichts vergessen...

MFG
Norman

Memo 29. Aug 2003 17:42

Re: Fehler beim beenden durch FormDestroy
 
Nimm aus deiner bass.pas das onClose-Event raus.

woki 29. Aug 2003 17:57

Re: Fehler beim beenden durch FormDestroy
 
Einfach mal so auf die Schnelle ein Schuß ins Blaue:
Wie gibst Du denn die form frei:
Schau dir mal in der Onlinehilfe von Delphi die Beschreibung von
TForm.release an.

Grüsse
Woki

NormanSteinmetz 30. Aug 2003 09:29

Re: Fehler beim beenden durch FormDestroy
 
Hallo,

habe mir mal die Onlinehilfe angesehen, viel steht da ja leider nicht. Ich bin jetzt aber etwas schauer geworden, sobald ich das release reinsetze dreht sich nun mein Problem um. Jetzt bekomme ich einen Fehler beim beenden wenn ich eben auf kein anderes Formular zugreife. Wenn ich dies nicht tue macht der release Befehl mir probleme. Es hat also was mit dem anderen Formularen zu tun auch wenn sie nicht sichtbar sind. Gibt es eine Möglichkeit festzustellen ob und welche Formulare aktiv waren bzw. ich drauf zugegriffen habe, denn die muss ich doch dann auch beenden sonst liegen sie doch noch im Speicher das gibt ja die Hilfe zu dem release an, er holt sie aus dem Speicher.

Memo noch eines zu Deinem Post... auch wenn ich die bass.pas weglasse kommt der Fehler, es hat definitiv nichts damit zu tun. Ich kann alles aus dem OnDestroy weglassen also BASS und BASS_FX und dennoch besteht der Fehler, zudem soll ja noch das zurückschreiben einer ini rein. Allein aus dem Grund besteht die Prozedur.

Ich habe selbst schon sehr lang dran gefummelt bevor ich hier den Thread reingesetzt habe aber es war vergebends leider.

MFG
Norman

woki 30. Aug 2003 09:47

Re: Fehler beim beenden durch FormDestroy
 
Hmm...

Schon mal mit debuggen versucht?
Es müßte sich dich etwas genauer feststellen lassen, welche Anweisung gnaue die Fehlermeldung verursacht.

Du mußt sicherstellen, daß die Form nirgends mehr verwendet wird, bevor Du sie aus dem Speicher entfernst.

Pointer sollten auf Nil gesetzt werden, etc, und vor dem Zugriff auf Gültigkeit geprüft werden, etc...

Grüsse
Woki

NormanSteinmetz 30. Aug 2003 10:50

Re: Fehler beim beenden durch FormDestroy
 
Hallo Woki,

Delphi schmeisst mir ja eine Debugger Meldung aus nur kann ich damit nicht wirklich etwas anfangen.

Ich weiss bzw habe eine Ahnung wo der Fehler liegt am beseten versuch ich es mal mit einem Teil des Quellcodes darzulegen.
Bisher hole ich mit vom Hauptformular was der Player ist Informationen über die Playlist in einem zweiten Formular. Dieses ist aktiv.

Delphi-Quellcode:
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {FORM_Player},
  Unit2 in 'Unit2.pas' {FORM_Equalizer},
  Unit3 in 'Unit3.pas' {FORM_INFO},
  Unit4 in 'Unit4.pas' {FORM_Configuration},
  Unit5 in 'Unit5.pas' {FORM_Playlist},
  Unit6 in 'Unit6.pas' {form_library},
  Unit7 in 'Unit7.pas' {Form_av},
  Unit8 in 'Unit8.pas' {Form_minibrowser};

{$R *.res}

begin
  Application.Initialize;
  Application.Title := 'Nostrobos X - 301';
  Application.CreateForm(TFORM_Player, FORM_Player);
  Application.CreateForm(TFORM_Equalizer, FORM_Equalizer);
  Application.CreateForm(TFORM_INFO, FORM_INFO);
  Application.CreateForm(TFORM_Configuration, FORM_Configuration);
  Application.CreateForm(TFORM_Playlist, FORM_Playlist);
  Application.CreateForm(Tform_library, form_library);
  Application.CreateForm(TForm_av, Form_av);
  Application.CreateForm(TForm_minibrowser, Form_minibrowser);
  Application.Run;
end.
Da ich auf keines der anderen Formulare zugreife sind die erstmal unrellevant. Sie playlist ist nicht sichtbar, sie besteht auch bisher nur über drei Komponenten Drivecombobox, Directorylistbox und Filelistbox.

Wenn ich den Player nun starte sehe ich nur den Player sonst nichts, beende ich ihn sofort wieder ist alles in Ordnung, keine Fehlermeldung kein garnichts, so wie es sein soll.
Drücke ich aber jetzt auf Play, so holt er sich folgende Informationen von der Filelistbox: count, itemindex und items. Das sieht dann so aus:

Delphi-Quellcode:
  iniplaylistposition := form_playlist.FileListBox1.ItemIndex;
  if iniplaylistposition > -1 then
  begin
  idfilename := Form_playlist.FileListBox1.Items[iniplaylistposition];
  BASS_start;
  image_play.Visible := true;
  image_stop.Visible := false;
  chan := BASS_streamcreatefile(false, pchar(idfilename), 0, 0, 0);
  label_title.Caption := idfilename;
  Slider_position.Position := 0;
  BASS_Streamplay(chan, false, 0);
  spielmodus := 'progress';
Wird das Programm jetzt beendet und OnDestroy aufgerufen bekomme ich folgende Meldung:

Benachrichtigung über Debugger-Exception
Im Project Project1.exe ist eine Exception der Klasse EAccsessViolation aufgetreten. Meldung:
'Zugriffsverletzung bei Adresse 004972AF in Modul 'Project1.EXE'. Lesen von Adresse FFFFFFF'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.

Die OnDestroy Prozedur ist nur im Hauptformular und in der Playlist ist nichts weiter als das was ich oben geschrieben habe. Während das Programm läuft bekomme ich keinen Fehler er tritt erst dann auf wenn ich das Programm beende. Es muss also etwas mit dem schliessen und freigeben der Formulare zu tun haben oder irre ich mich da?

MFG
Norman

[edit=Daniel B]Delphi-Tags eingefügt. Mfg, Daniel B[/edit]

ich habe gerade gesehen das folgende Zeile Makiert ist:
iniplaylistposition := form_playlist.FileListBox1.ItemIndex;

woki 30. Aug 2003 17:31

Re: Fehler beim beenden durch FormDestroy
 
Zitat:

program Project1;
Nun, da springt er hin, nachdemn es geknallt hat, das ist nicht sehr hilfreich.

Eines vorweg: Du weißt, was eine "access violation" ist und wie es dazu kommt?
Du kennst die Unterschiede von free, destroy und weißt wozu freeandnil gut ist?

Diese Sachen zu klären wäre wichtig, dann gehe im Einzelkschrit Mode durch den verdächtigen Code, und finde die Zeile, bei der es knallt.

Grüsse
Woki

Nocheinmal: Vergiß nicht, alle Zeiger, die auf irgendetwas auf der Form zeigen,die du aus dem Speicher entfernst, nil zu setzen, und sie vor einem Zugriff auf nil zu prüfen.

Grüsse
Woki

NormanSteinmetz 31. Aug 2003 01:23

Re: Fehler beim beenden durch FormDestroy
 
Hallo Woki,

der obere Code ist die Project Datei. er springt dorthin:

Delphi-Quellcode:
iniplaylistposition := form_playlist.FileListBox1.ItemIndex;
Ich habe eigentlich keine Ahnung was die Unterschiede von Free und Destroy ist auch habe ich keine Ahnung wozu Freeannil gut ist.

Free lässt doch die zugehörigen prozeduren frei und gbit den Speicher wieder frei wenn ich mich da nicht irre. Auf das Destroy bin ich per Zufall im Netz gestossen beim stöbern, da hatte jemand das Problem das er auch Daten speichern wollte wenn das Programm nicht auf übliche Weise beendet wird wie z.B. duch einen Neustart. Dies habe ich praktisch übernommen aber mich leider auch nicht weiter drüber informiert.
Das letze was Du ansprichts verstehe ich leider auch nicht so ganz, wie gesagt ich beschäftige mich damit noch nicht sehr lange.
Ich habe ja auch schon im Netz gesucht doch so recht finde ich nicht das was ich wirklich suche, nen Wolf habe ich mir schon gesucht. Ich werde versuchen mich darüber zu informieren, aber wenn Du eine Tip hast wie ich weiter komme wäre ich Dir dennoch sehr dankbar. Dies gilt natürlich auch für andere... :)

Gruss
Norman

Luckie 31. Aug 2003 06:18

Re: Fehler beim beenden durch FormDestroy
 
Also, mein Schlaues Buch (Hast du übrigens auch. :roll:)sagt, dass Free quasi ein Wrapper für Destroy ist. Man soll Destroy nie direkt aufrufen, sondern über Free gehen. Denn Free prüft vorher, ob der Zeiger auf das Objekt noch gültig ist und ruft dann Destroy auf.

Destroy zerstört das Objekt und gi´bt den Speicher wieder frei. Aber der Zeiger wird nicht auf nil gesetzt, wäre nach Destroy also noch gültig. Da aber das Objekt im Speicher nicht mehr existent ist, fliegt dir der ganze Kram bei einem Zugriff um die Ohren. Ein Test auf nil
Delphi-Quellcode:
if Object <> nil
würde also auch nach dem Destroy nicht funktionieren, da der Zeiger noch existiert. Man muß den Zeiger also explizit von Hand auf nil setzten oder man benutzt FreeAndNil, welches das automatisch macht.

Man sollte den Zeiger übrigens immer "nillen" (Was für ein Wort. :mrgreen:), weil dann nämlich der Test auf nil klappt und man sich so bei einem erneuten Zugriff absichern kann.

Das war das Wort zum Sonntag, es sprach Pfarrer Luckie zum Thema Free, Destroy und FreeAndNil.

woki 31. Aug 2003 10:23

Re: Fehler beim beenden durch FormDestroy
 
Delphi-Quellcode:

iniplaylistposition := form_playlist.FileListBox1.ItemIndex;
nun, das sieht nun so aus, als sei form_playlist oder eventuell auch FileListBox1 zu dem Zeitpunkt dieses Zugriffes bereits zerstört.

Also, das was Luckie da beschrieben hat, mußt Du an diese Stelle einfach verstehen, um hier weiterzukommen, die eingesetzte Zeit lohnt sich aber, denn das brauchst Du nicht nur hier für dein Formproblem, sondern für den Umgang mit selbst erzeugten Objekten im immer, und wenn Du es nicht selber tun mußt, passiert es im Hintergrund, und da hilft es auch, wenn man es versteht.

Fang am Besten an bei create:

Was passiert, wenn ein Objekt erzeugt wird, also

MyObject := TMyObject.create

TMyObject.create erzeugt das Objekt, und gibt einen Zeiger auf das Objekt zurück, der in der Variablen MyObject gespeichert wird.
Das ist der Anfang, und das Ende dann siehe Luckie

Grüsse
Woki

NormanSteinmetz 31. Aug 2003 14:35

Re: Fehler beim beenden durch FormDestroy
 
Hallo,

habe die Lösung gefunden, als ich den Thread geschrieben habe lag ich falsch mit meiner vermutung das der Fehler am schliessen der anderen Formulare liegt, von Anfang an lag das Problem wo anders. Ich habe mir den Teil des Codes zum schliessen nochmal angesehen und bin dann da auf etwas gestossen und es hat sich als richtig erwiesen. in meinem Player sind 2 Timer die jeweils auf 1 und der andere auf 33 Millisekunden. Wenn das Destroy Event aufgerufen wird sind beide Timer noch aktiv und da liegt der Fehler. Er hat bereits alle Formulare bis auf das Hauptformular geschlossen. Der Timer der die Funktion des Abspielen steuert ist aber noch aktiv und möchte immernoch auf die Playlist zugreifen und da sie nicht da ist kommt dann der Fehler. Mir ist nun auch klar warum der Fehler auch erst auftaucht wenn ich auf ein anderes Formular zugegriffen habe denn vorher ist der Timer nicht aktiv.

Ich habe jetzt einfach nur on Destroy Event beide Timer abgeschaltet und siehe da ich kann das Programm Ordnungsgemäss beenden.

Ich danke euch dennoch vielmals für euere Hilfe und ihr habt mir gezeigt das ich noch einiges zu bewältigen habe mit Delphi. Von dem Timer wusste hier keiner da ich es ja nie erwähnt habe.

Ich will auch sagen ich habe jeden Rat von euch ernst genommen und ausprobiert. Was muss ich tun und dieses Thema abzuschliessen oder kann ich das so stehenlassen?

MFG und Dank an euch
Norman


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