![]() |
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 |
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 |
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 |
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:
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.
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. 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:
Wird das Programm jetzt beendet und OnDestroy aufgerufen bekomme ich folgende Meldung:
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'; 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; |
Re: Fehler beim beenden durch FormDestroy
Zitat:
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 |
Re: Fehler beim beenden durch FormDestroy
Hallo Woki,
der obere Code ist die Project Datei. er springt dorthin:
Delphi-Quellcode:
Ich habe eigentlich keine Ahnung was die Unterschiede von Free und Destroy ist auch habe ich keine Ahnung wozu Freeannil gut ist.
iniplaylistposition := form_playlist.FileListBox1.ItemIndex;
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 |
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:
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.
if Object <> nil
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. |
Re: Fehler beim beenden durch FormDestroy
Delphi-Quellcode:
nun, das sieht nun so aus, als sei form_playlist oder eventuell auch FileListBox1 zu dem Zeitpunkt dieses Zugriffes bereits zerstört. iniplaylistposition := form_playlist.FileListBox1.ItemIndex; 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 |
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:09 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