![]() |
Fehler nach Schließen
Hallo,
ich darf als Hausaufgabe ein kleines Spiel programmieren (ein Ping-Pong). Das ist soweit alles kalr, doch habe ich hier zum ersten Mal ein zweites Formular in einem Program. Nachdem ich es mit Hilfe dieses Forums und der Hilfe hinbekommen habe aus dem einen das andere Formular zu öffnen gibt es jetzt immer eine Fehlermeldung nachdem ich das Program schließe (entweder mit dem x des Fenster, oder über den Beenden-Button:
Delphi-Quellcode:
Die Fehlermeldung lautet: "Im Projekt bewegen.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 00000000. Lesen von Adresse 0000000'. [...]"
procedure TForm1.Button3Click(Sender: TObject);
begin Application.Terminate; end; Woran könnte das liegen? Wäre euch für eine Antwort sehr dankbar! Theo1994 |
AW: Fehler nach Schließen
Es wird auf ein nicht initialisiertes OIbjekt zugegriffen.
Btw. wenn Form1 die Hauptform ist, wird das Programm eh beendet, wenn dieses Fenster geschlossen wird. |
AW: Fehler nach Schließen
Das nicht inizialisiert Objekt müsste dann das Form1 sein. Muss dann irgendwo Form1.inizialize rein, und wenn ja wo?
Danke Theo1994 |
AW: Fehler nach Schließen
Eigentlich sollte das automatisch passieren, wenn das Formular automatisch erzeugt wird. Zeige mal deine Projektdatei.
|
AW: Fehler nach Schließen
Nein, muß es nicht ... mit nicht initialisiert meinte er, daß ein Objekt nicht exisitert, bzw. nicht erstellt wurde.
Irgendwo ist eine Zeiger-Variable (Pointer, Objekt oder Sonstwas) mit dem Inhalt NIL und dein Programm greift auf den Inhalt dieses Zeigers zu, welcher ja nicht existiert. Und zu dem was, schon gesagt wurde: Wenn Form1 die Hauptform ist, dann nutze Close, um das Programm zu beenden. [add] Zitat:
Zitat:
Aber an Adresse 00000000 bis 0000ffff existiert für dich garatiert keinerlei Programmcode. Also wird hier wohl irgendwo ein Sprung falsch sein ... z.B. ein nichtgesetzer Ereignishandler (Prozedur-/Methodenzeiger), welcher aufgerufen wird. |
AW: Fehler nach Schließen
Wenn Form1 nicht instanziert wäre, könntest Du darauf auch keinen Button anklicken. Machst Du noch etwas im FormClose oder FormCloseQuery?
|
AW: Fehler nach Schließen
Ok:
Die Programmdatei:
Delphi-Quellcode:
Die Unit vom ersten Form:
program bewegen;
uses Forms, Eingabe in 'eingabe.pas' {FormE}, ubewegen in 'ubewegen.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.CreateForm(TFormE, FormE); Application.Run; Application.Destroy; //mit Application.free kommt der gleiche Fehler {ohne einem der beiden kommt zwar die Meldung nicht, aber das Programm erscheint auch nicht wieder in Delphi ohne Strg+F2 zu drücken (passiert nach den Meldungen auch nicht)} end.
Delphi-Quellcode:
Und das Form1:
unit Eingabe;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ubewegen; type TFormE = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Edit1: TEdit; Edit2: TEdit; ScrollBar1: TScrollBar; Button1: TButton; Label5: TLabel; procedure ScrollBar1Change(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var FormE: TFormE; implementation {$R *.dfm} procedure TFormE.ScrollBar1Change(Sender: TObject); //... procedure TFormE.Button1Click(Sender: TObject); begin Application.CreateForm(TForm1,Form1); //Formular mit Spiel aufbauen Form1.Label1.Caption:=FormE.Edit1.Text; //Eingegebenen Name für Spieler 1 übergeben Form1.Label2.Caption:=FormE.Edit2.Text; //Eingegebenen Namen für Spieler 2 übergeben Form1.Label5.Caption:=IntToStr(FormE.ScrollBar1.Position); //Übergabe der Gewinnpunktzahl FormE.Destroy; //Eingabe-Formular schließen Form1.Show; //Spiel-Formular anzeigen end; end.
Delphi-Quellcode:
unit ubewegen;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Math; type TForm1 = class(TForm) Timer1: TTimer; Feld: TShape; Ball: TShape; Button2: TButton; EditTastenEingabe: TEdit; Schl2: TShape; Button1: TButton; Schl1: TShape; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Button4: TButton; Button3: TButton; procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure EditTastenEingabeKeyPress(Sender: TObject; var Key: Char); procedure Aus (Seite: Byte); procedure Button4Click(Sender: TObject); procedure FormActivate(Sender: TObject); procedure Angabe (Seite: Byte); procedure BallPos (x,y: Integer); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; x1, y1: Integer; //Position des Balles zum Rechnen Durchmesser: Byte; //Durchmesser des Balles um ggf. einzustellen Hoch: Integer; //Bewegung des Balles nach oben (in Pixeln je Timer) //wenn negativ -> nach unten Rechts: Integer; //Bewegung des Balles nach rechts (in Pixeln je Timer) //wenn negativ -> nach links Sp1Name, Sp2Name: Shortstring; //Spielernammen Gewinnpkt: Word; //Spielstand, bei dem ein Spieler gewonnen hat Seite: Word; //Seitenangabe Speed: Byte; //Geschwindigkeit des Balles (in Pixeln je Timer) implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin //Variable Durchmesser mit Durchmesser des Balles belegen Durchmesser:=Ball.Width; end; procedure TForm1.FormActivate(Sender: TObject); begin //... end; procedure TForm1.Button2Click(Sender: TObject); begin //noch leer, das wird der Neustart des Spiels end; procedure TForm1.Button1Click(Sender: TObject); begin //noch leer, das wird Neues Spiel -> Aufruf FormE end; //---------------------------------------------------------------------- procedure TForm1.Timer1Timer(Sender: TObject); //zeitliche Schrittbestimmung des Balles begin //... Verschiebung des Balles mit verschiedenen Prüfungen end; procedure TForm1.EditTastenEingabeKeyPress(Sender: TObject; var Key: Char); begin //... Steuerung der Schläger end; procedure TForm1.Aus(Seite: Byte); //wenn der Ball hinter die Seitenlinie kommt begin //... Einsetzen des Balls end; procedure TForm1.Button4Click(Sender: TObject); (Beenden-Button) begin Application.Terminate; end; procedure TForm1.Angabe (Seite: Byte); begin //... neue Angabe des Balles end; procedure TForm1.BallPos(x,y: Integer); begin Ball.Left:=x; Ball.Top:=y; end; end. Ich hoffe, ich habe alles unwichtige rausgestrichen und alles wichtige drin gelassen... @DeddyH: Diese beiden Dinge habe ich noch nie gehört... Also unwahrscheinlich... Ich habe auch nichts gegen das rausschmeißen des Beenden-Buttons, aber mein Lehrer will den immer mit haben...:( Danke auch schonmal für die schnellen Kommentare. Theo1994 |
AW: Fehler nach Schließen
Nimm die ganzen Destroy-Aufrufe raus.
|
AW: Fehler nach Schließen
Danke, so kommt der Fehler nicht mehr.
Bleibt nur das FormE sichtbar, das mache ich dann mit
Delphi-Quellcode:
unsichtbar und jetzt gehts.
FormE.visible:=False
Stellt sich mir die Frage, wozu man das Desrtoy verwendet? Danke an alle, die mir da geholfen haben! Theo1994 |
AW: Fehler nach Schließen
Direkt gar nie, entweder werden sie von ihrem Owner freigegeben ( beim Formular Application) oder man ruft .Free auf, welches verschidene Überprüfungen ausführt und dann .Destroy aufruft).
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:26 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