Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung bei Zeichnen auf Bitmap (https://www.delphipraxis.net/127236-zugriffsverletzung-bei-zeichnen-auf-bitmap.html)

SuperSeb 9. Jan 2009 17:00


Zugriffsverletzung bei Zeichnen auf Bitmap
 
Hallo DP-Gemeinde,

ich würde gerne im Constructor ein Bitmap erzeugen und dann später andere Funktionen innerhalb einer Oberflächen-Klasse darauf zeichnen lassen. Die Organisation der Klassen sieht wie folgt aus:

Delphi-Quellcode:
TOberflaeche = class(TForm)
private
  BMP: TBitmap;
//(...)
und

Delphi-Quellcode:
TAndereKlasse = class(TOberflaeche)
//(...)
Der Constructor von TOberflaeche sieht so aus:

Delphi-Quellcode:
constructor TOberflaeche.Create;
begin
  inherited Create(Application);
  BMP := TBitmap.Create;
  //dann zum Beispiel:
  BMP.Width := 500;
  BMP.Height := 500;
  ShowMessage(inttostr(BMP.Width));
end;
Das funktioniert soweit einwandfrei. Nun das Problem: Wenn ich aus einer anderen Prozedur auf BMP zugreife, erzählt mir der Compiler
Zitat:

(...)Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse (...)'
Das kann doch nicht sein, dass eine Methode der Klasse nicht auf deren Eigenschaften zugreifen dürfen soll...

Delphi-Quellcode:
procedure TOberflaeche.ErzeugeMalKeinenFehler;
begin
  ShowMessage(inttostr(BMP.Width));
end;
Gleicher Code, nur nicht im Constructor... Und bevor einer was sagt: Ja, ich habe google reichlich verwendet und ja, ich habe auch immer schön ein Objekt erzeugt, bevor ich darauf zugreifen wollte


Kann mir das irgendwie nicht erklären, wo das Problem sein soll...

Gruß

Seb

mkinzler 9. Jan 2009 17:06

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Sollte es nicht
Delphi-Quellcode:
constructor TOberflaeche.Create( AOwner: TComponent);
heissen?

nahpets 9. Jan 2009 17:12

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Hallo,

die Fehlermeldung klingt eigentlich so, als sei irgendwo ein Create vergessen oder was schon freigegeben worden, bevor man drauf zugreift. Könntest Du uns bitte den ganzen Code zeigen, so kann ich erstmal keinen Fehler sehen.

Wo wird das TOberflaeche.Create letztlich aufgerufen und bei welcher Aktion produziert TOberflaeche.ErzeugeMalKeinenFehler doch einen Fehler?

SuperSeb 9. Jan 2009 17:13

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Habs dahingehend geändert - Fehler bleibt jedoch. Owner des Objekts der anderen Klasse is jetzt bei mir Application, also:

Delphi-Quellcode:
AndereKlasse := TAndereKlasse.Create(Application);
@nahpets: wie schon gesagt, meine andere Klasse erbt alles von TOberfläche. Davon wird dann ein Objekt erzeugt (s.o.). Diese Prozedur mit dem tollen Namen ErzeugeMalKeinenFehler stammt ja wie der Constructor von der Basisklasse und müsste genau so wie dieser auf BMP zugreifen können.

Zitat:

die Fehlermeldung klingt eigentlich so, als sei irgendwo ein Create vergessen oder was schon freigegeben worden, bevor man drauf zugreift.
Wie gesagt: Der Quellcode wurde dahingehend schon untersucht und enthält noch keine Objektfreigaben, das kommt später noch. Außerdem sind alle Creates (sinn ja nich soo viele) vorhanden, die man braucht.

QuickAndDirty 9. Jan 2009 17:15

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Kannst du den Code mal Vollständig posten?

DeddyH 9. Jan 2009 17:15

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Geht das unter .NET nicht ganz anders?

SirThornberry 9. Jan 2009 17:22

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Also das es hier um .Net geht bezweifel ich langsam auch. Zudem: Warum übergibst du als Owner Application und nicht den Owner der wirklich übergeben wurde (wenn man richtig vererbt)?
Und könntest du bitte die vollständige Fehlermeldung posten inklusive der Adressen die dir angezeigt werden? Die Adressen können nämlich sehr viel über die möglichen Fehler aussagen.

nahpets 9. Jan 2009 17:29

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Hallo,

weiß nicht, ob ich mich da jetzt täusche, liegt der Hund eventuell hier begraben?
Delphi-Quellcode:
constructor TAndereKlasse.Create;
begin
  inherited Create;
  ....
Wird im Konstruktor der TAndereKlasse der Konstruktor des Vorfahren aufgerufen? (Oder passiert das implizit? eigentlich doch nicht? oder doch oder wie oder?)

SuperSeb 9. Jan 2009 17:36

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
So, bitteschön: Der Code. Kann ihn leider nicht ganz posten, hab ihn aber auf die Kernelemente reduziert und getestet, dass auch ja der Fehler bleibt...

Delphi-Quellcode:
unit Vordergrundunit;

interface

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

type
  TOberflaeche = class(TForm)
  private
    BMP: TBitmap;
    procedure ErzeugeMalKeinenFehler;
  public
    constructor Create(AOwner: TComponent);
  end;

  TAndereKlasse = class(TOberflaeche)
    BTestbutton: TButton;
    procedure BTestbuttonClick(Sender: TObject);
  end;

var
  AndereKlasse: TAndereKlasse;

implementation

{$R *.dfm}

constructor TOberflaeche.Create(AOwner: TComponent);
begin
  inherited Create(Application);
  BMP := TBitmap.Create;
  BMP.Width := 500;
  BMP.Height := 500;
end;

procedure TOberflaeche.ErzeugeMalKeinenFehler;
begin
  ShowMessage(inttostr(BMP.Width));
end;

procedure TAndereKlasse.BTestbuttonClick(Sender: TObject);
begin
  ErzeugeMalKeinenFehler;
end;

initialization
  AndereKlasse := TAndereKlasse.Create(Application);

end.

nahpets 9. Jan 2009 18:05

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Hallo,

so hat's bei mir funktioniert:
Delphi-Quellcode:
unit Unit1;

interface

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

type
  TOberflaeche = class(TForm)
    // wahrscheinlich so nicht gewünscht.
    BTestButton: TButton; // geändert, von AndereKlasse nach hier
    procedure BTestButtonClick(Sender: TObject); // geändert, von AndereKlasse nach hier
  private
    BMP: TBitmap;
    procedure ErzeugeMalKeinenFehler;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TAndereKlasse = class(TOberflaeche)
    constructor Create(AOwner: TComponent); override; // Neu
    procedure BTestbuttonClick(Sender: TObject);
  end;

var
  AndereKlasse: TAndereKlasse;

var
  Oberflaeche: TOberflaeche;

implementation

{$R *.dfm}

constructor TOberflaeche.Create(AOwner: TComponent);
begin
  inherited; // geändert
  // Create(AOwner); Der führt beim Aufruf vom Create schon zu einer Zugriffverletzung
  BMP := TBitmap.Create;
  BMP.Width := 500;
  BMP.Height := 500;
end;

procedure TOberflaeche.ErzeugeMalKeinenFehler;
begin
  ShowMessage(inttostr(BMP.Width));
end;

constructor TAndereKlasse.Create(AOwner: TComponent); // Neu
begin
  inherited;
end;

procedure TAndereKlasse.BTestbuttonClick(Sender: TObject);
begin
  ErzeugeMalKeinenFehler;
end;

procedure TOberflaeche.BTestbuttonClick(Sender: TObject); // geändert von TAndereKlasse nach TOberflaeche
begin
  AndereKlasse.BTestbuttonClick(sender);
end;

initialization
  AndereKlasse := TAndereKlasse.Create(Application);

end.
Das Hauptproblem ist im Bereich der Konstruktoren zu suchen. Der Nachfahre (TAndereKlasse) benötigt einen eigenen Konstruktor, der den des Vorgängers aufruft. Application als Owner anzugeben scheint sehr schief zu gehen.

Achso, das ist bestimmt kein .NET, bitte ändere den ersten Post entsprechend (wenn das geht).

SuperSeb 9. Jan 2009 18:35

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Danke an nahpets und all die anderen, die sich hier ins Zeug gelegt haben!

Hab doch tatsächlich

Delphi-Quellcode:
override;
vergessen... Sehr nachlässig von mir... Stand aber auch schon mal in ner früheren Version da. Naja gut. Soweit funktionierts und du (nahpets) hattest Recht, es liegt wirklich an "den Konstruktoren" (war zwar nur der eine, aber egal).

Zum Abschluss noch eine Frage: Was würdet ihr denn statt Application als Owner vorschlagen? AndereKlasse würd ich sagen, denn dem Objekt gehört es ja (is irgendwie logisch, dass es sich selbst gehört)...


Ach ja: @nahpets Ich wollte absichlich nicht irgendwelche Button-Prozeduren in die Oberflächenklasse ziehen. Dafür hatte ich extra die AndereKlasse, um das ein bisschen sauberer zu trennen und wiederverwendbarer zu machen.


Gruß

Seb

mkinzler 9. Jan 2009 18:36

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Application sollte ok sein.

SuperSeb 9. Jan 2009 18:40

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
??? Was denn nu?

Zitat:

Application als Owner anzugeben scheint sehr schief zu gehen.
und

Zitat:

Application sollte ok sein.

Kann mir das jetzt einer definitiv sagen? Also mit Application funktionierts zumindest und dann sollte ja auch alles wieder sauber befreit werden, wenn der Prozess beendet ist. (Ja, die Klasse kriegt trotzdem n Destruktor, falls der Standard-Destruktor nicht ausreicht. Aber erst ma schaun, was noch so dazukommt...)

mkinzler 9. Jan 2009 18:42

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Vielleicht solltest du den Parameter noch durchschleifen:
Delphi-Quellcode:
constructor TOberflaeche.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
...

SuperSeb 9. Jan 2009 18:51

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Hab ich gemacht und funktioniert - war nicht anders zu erwarten - ebenfalls.

Vielleicht kann ja noch mal jemand anderes zu der Application-oder-nicht-Application-Geschichte Stellung beziehen (vllt. mit Begründung?).

DeddyH 9. Jan 2009 21:31

Re: Zugriffsverletzung bei Zeichnen auf Bitmap
 
Na, Du gibst dem Kontruktor doch einen Owner mit. Wenn Du diesen aber innerhalb des Konstruktors wieder ignorierst und fix auf Application setzt, macht der Parameter ja keinen Sinn mehr ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:19 Uhr.

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