Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Fehler nach Schließen (https://www.delphipraxis.net/159868-fehler-nach-schliessen.html)

Theo1994 16. Apr 2011 10:01

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:
procedure TForm1.Button3Click(Sender: TObject);
begin
  Application.Terminate;
end;
Die Fehlermeldung lautet: "Im Projekt bewegen.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 00000000. Lesen von Adresse 0000000'. [...]"

Woran könnte das liegen?

Wäre euch für eine Antwort sehr dankbar!

Theo1994

mkinzler 16. Apr 2011 10:05

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.

Theo1994 16. Apr 2011 10:15

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

mkinzler 16. Apr 2011 10:16

AW: Fehler nach Schließen
 
Eigentlich sollte das automatisch passieren, wenn das Formular automatisch erzeugt wird. Zeige mal deine Projektdatei.

himitsu 16. Apr 2011 10:18

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:

Lesen von Adresse 000000xx
etwas existiert nicht
Zitat:

Zugriffsverletzung bei Adresse 00000000
Wobei dies eigentlich die Code-Adresse ist, dessen Codes, welcher den zugreifenden Befehl enthält.
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.

DeddyH 16. Apr 2011 10:19

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?

Theo1994 16. Apr 2011 10:43

AW: Fehler nach Schließen
 
Ok:
Die Programmdatei:
Delphi-Quellcode:
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.
Die Unit vom ersten Form:
Delphi-Quellcode:
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.
Und das Form1:
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

DeddyH 16. Apr 2011 11:02

AW: Fehler nach Schließen
 
Nimm die ganzen Destroy-Aufrufe raus.

Theo1994 16. Apr 2011 11:44

AW: Fehler nach Schließen
 
Danke, so kommt der Fehler nicht mehr.
Bleibt nur das FormE sichtbar, das mache ich dann mit
Delphi-Quellcode:
FormE.visible:=False
unsichtbar und jetzt gehts.

Stellt sich mir die Frage, wozu man das Desrtoy verwendet?

Danke an alle, die mir da geholfen haben!
Theo1994

mkinzler 16. Apr 2011 11:49

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 14:58 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz