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/)
-   -   EAccessViolation beim aufrufen der eigenen Klasse (https://www.delphipraxis.net/109552-eaccessviolation-beim-aufrufen-der-eigenen-klasse.html)

Lee500 3. Mär 2008 14:38


EAccessViolation beim aufrufen der eigenen Klasse
 
Folgendes Problem:

In der MainGame.pas

Delphi-Quellcode:
unit MainGame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Paint, ExtCtrls;

type
  TMain = class(TForm)
    PaintBox: TPaintBox;
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Main: TMain;
  Painter: TPaint;

implementation

{$R *.dfm}

procedure TMain.FormActivate(Sender: TObject);
begin
  Main.Width := Screen.Width;
  Main.Height := Screen.Height;
  Painter := TPaint.Create(PaintBox);
end;

procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Painter.Destroy;
end;

end.
wird meine PainterKlasse (TPaint) erstmal erzeugt.
Daraufhin bekomme ich beim erzeugen der Klasse eine EAccessViolation.

Hier der Code der Painterklasse:

Delphi-Quellcode:
unit Paint;

interface
uses Graphics, Classes, ExtCtrls;

type
  TPaint = class
  private
    Colors: array [0..7] of array [0..7] of Boolean;
    Size: Integer;
    PenBlack, PenWhite: TPen;
    BrushBlack, BrushWhite: TBrush;
  protected

  public
    constructor Create(PaintBox: TPaintBox);
    destructor Destroy();
    procedure Paint(C: TCanvas);
  end;

implementation

uses MainGame;

 constructor TPaint.Create(PaintBox: TPaintBox);
 var
   X,Y: Integer;
   Bool: Boolean;
 begin
   inherited Create();
   self.Size := PaintBox.Height div 8;
   self.PenBlack.Color := clblack;
   self.PenWhite.Color := clwhite;
   self.PenBlack.Width := 1;
   self.PenWhite.Width := 1;
   self.BrushBlack.Color := clBlack;
   self.BrushWhite.Color := clWhite;
   Bool := true;
   for X := 0 to Length(Colors)-1 do
   begin
     for Y := 0 to Length(Colors[X])-1 do
     begin
       Colors[X,Y] := Bool;
       if Bool then
       begin
         Bool := false;
       end else
       begin
         Bool := true;
       end;
     end;
   end;
 end;

 destructor TPaint.Destroy();
 begin
 inherited Destroy;
   self.Free;
 end;

 procedure TPaint.Paint(C: TCanvas);
 var
   X,Y: Integer;
 begin
   for X := 0 to Length(self.Colors)-1 do
   begin
     for Y := 0 to Length(self.Colors[X])-1 do
     begin
       if self.Colors[X,Y] then
       begin
         C.Pen := self.PenWhite;
         C.Brush := self.BrushWhite;
       end else
       begin
         C.Pen := self.PenBlack;
         C.Brush :=self.BrushBlack;
       end;
       C.Rectangle(Rect(X*Size,Y*Size,(X+1)*Size,(Y+1)*Size));
     end;
   end;
 end;

end.
Ich hab auch schon gegoogelt udn auch die Foren Suche benutzt, habe jedoch nichts passendes gefunden. Ich hoffe ihr könnt mir helfen. Schonma im vorraus Danke :)

Neutral General 3. Mär 2008 14:40

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Hi,

2 Sachen die das Problem sind:

:arrow: Du solltest Painter.Free aufrufen und nicht Painter.Destroy;

:arrow:
Delphi-Quellcode:
destructor TPaint.Destroy();
begin
   inherited Destroy;
   self.Free; //  <--- das erzeugt die AV. Das ist TÖDLICH!
end;
Gruß
Neutral General

Muetze1 3. Mär 2008 14:41

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
1. Überprüfe ob PaintBox1 schon angelegt worden ist (ungleich NIL)
2. TBrush und TPen sind Klassen und müssen von dir in deiner Klasse auch instanziiert werden
3. Der Destruktor muss mit Override deklariert werden.

/EDIT: Neutral General: Destroy direkt aufzurufen ist nicht unbedingt tötlich, wenn man vorher selbst dafür sorgt, dass die Instanz nicht nil ist (oder werden kann). Ausserdem erscheint der Fehler beim Constructor Aufruf nach Beschreibung, somit kann es nicht deine Vermutung sein...

shmia 3. Mär 2008 14:42

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Delphi-Quellcode:
constructor TPaint.Create(PaintBox: TPaintBox);
var
   X,Y: Integer;
   Bool: Boolean;
begin
   inherited Create();
   self.Size := PaintBox.Height div 8;
   self.PenBlack.Color := clblack;   // hier macht es Budsch, weil Objekt PenBlack nicht erzeugt wurde !!
Du kannst mit Delphi auch debuggen!
Mit Breakpoints setzen und Einzelschrittmodus kann man diese Art von Fehlern leicht selber entdecken.

Neutral General 3. Mär 2008 14:43

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Zitat:

Zitat von Muetze1
/EDIT: Neutral General: Destroy direkt aufzurufen ist nicht unbedingt tötlich, wenn man vorher selbst dafür sorgt, dass die Instanz nicht nil ist (oder werden kann). Ausserdem erscheint der Fehler beim Constructor Aufruf nach Beschreibung, somit kann es nicht deine Vermutung sein...

Das habe ich auch nicht gesagt, aber Free; im Destructor aufzurufen ist tödlich :P

Lee500 3. Mär 2008 14:52

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Problem gelöst. Es lag wirklich daran, dass die Pen und die Brush Klassen nicht erzeugt wurden.


Zitat:

Zitat von shmia
Du kannst mit Delphi auch debuggen!
Mit Breakpoints setzen und Einzelschrittmodus kann man diese Art von Fehlern leicht selber entdecken.

Das hab ich auch versucht. Aber irgendwie scheine ich zu blöd dafür zu sein -.- Ich habe sogar den Kompletten Konstruktor einmal auskommentiert und trotzdem gab es noch die EAccessViolation. Naja egal. Nun weiß ich wo der Fehler lag. Danke!!

Neutral General 3. Mär 2008 14:53

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Will ja nicht nerven aber das Self.Free solltest du aus dem Destructor werfen ;)

Lee500 3. Mär 2008 15:20

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Hab ich ja. Oh sry. Hab vergessen das zu erwähnen^^

Hier nochmal der ganze Code:

Delphi-Quellcode:
unit MainGame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Paint, ExtCtrls;

type
  TMain = class(TForm)
    PaintBox: TPaintBox;
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Main: TMain;
  Painter: TPaint;

implementation

{$R *.dfm}

procedure TMain.FormActivate(Sender: TObject);
begin
  Main.Width := Screen.Width;
  Main.Height := Screen.Height;
  Painter := TPaint.Create(PaintBox);
end;

procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Painter.Destroy;
end;

end.
Delphi-Quellcode:

unit Paint;

interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;

type
  TPaint = class
  private
    Colors: array [0..7] of array [0..7] of Boolean;
    Size, Space: Integer;
    PenBlack, PenWhite: TPen;
    BrushBlack, BrushWhite: TBrush;
  protected

  public
    constructor Create(PaintBox: TPaintBox);
    destructor Destroy(); override;
    procedure Paint(C: TCanvas);
  end;

implementation

uses MainGame;

 constructor TPaint.Create(PaintBox: TPaintBox);
 var
   X,Y: Integer;
   Bool: Boolean;
 begin
   inherited Create();
   self.Size := (PaintBox.Height-100) div 8;
   self.Space := (PaintBox.Width - PaintBox.Height + 100) div 2;
   self.PenBlack := TPen.Create;
   self.PenWhite := TPen.Create;
   self.BrushBlack := TBrush.Create;
   self.BrushWhite := TBrush.Create;
   self.PenBlack.Color := clblack;
   self.PenWhite.Color := clwhite;
   self.PenBlack.Width := 5;
   self.PenWhite.Width := 5;
   self.BrushBlack.Color := clBlack;
   self.BrushWhite.Color := clWhite;
   Bool := true;
   for X := 0 to Length(Colors)-1 do
   begin
     for Y := 0 to Length(Colors[X])-1 do
     begin
       Colors[X,Y] := Bool;
       if Bool then
       begin
         Bool := false;
       end else
       begin
         Bool := true;
       end;
     end;
     if Bool then
     begin
       Bool := false;
     end else
     begin
       Bool := true;
     end;
   end;
 end;

 destructor TPaint.Destroy;
 begin
   self.PenBlack.Free;
   self.PenWhite.Free;
   self.BrushBlack.Free;
   self.BrushWhite.Free;
 end;

 procedure TPaint.Paint(C: TCanvas);
 var
   X,Y: Integer;
 begin
   for X := 0 to Length(self.Colors)-1 do
   begin
     for Y := 0 to Length(self.Colors[X])-1 do
     begin
       if self.Colors[X,Y] then
       begin
         C.Pen := self.PenWhite;
         C.Brush := self.BrushWhite;
       end else
       begin
         C.Pen := self.PenBlack;
         C.Brush :=self.BrushBlack;
       end;
       C.Rectangle(Rect(Space+X*Size,50+Y*Size,Space+(X+1)*Size,50+(Y+1)*Size));
     end;
   end;
 end;

end.

DeddyH 3. Mär 2008 15:27

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
Zitat:

Zitat von Lee500
Delphi-Quellcode:
       if Bool then
       begin
         Bool := false;
       end else
       begin
         Bool := true;
       end;

Wie wäre es mit
Delphi-Quellcode:
Bool := not Bool;
?

Lee500 3. Mär 2008 15:47

Re: EAccessViolation beim aufrufen der eigenen Klasse
 
mh joa sieht auf jedenfall schicker aus :)Naja ich programmiere auch nicht so viel. Aber danke für den Tipp. Ich werds mir merken ;-)


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