![]() |
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:
und
TOberflaeche = class(TForm)
private BMP: TBitmap; //(...)
Delphi-Quellcode:
Der Constructor von TOberflaeche sieht so aus:
TAndereKlasse = class(TOberflaeche)
//(...)
Delphi-Quellcode:
Das funktioniert soweit einwandfrei. Nun das Problem: Wenn ich aus einer anderen Prozedur auf BMP zugreife, erzählt mir der Compiler
constructor TOberflaeche.Create;
begin inherited Create(Application); BMP := TBitmap.Create; //dann zum Beispiel: BMP.Width := 500; BMP.Height := 500; ShowMessage(inttostr(BMP.Width)); end; Zitat:
Delphi-Quellcode:
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
procedure TOberflaeche.ErzeugeMalKeinenFehler;
begin ShowMessage(inttostr(BMP.Width)); end; Kann mir das irgendwie nicht erklären, wo das Problem sein soll... Gruß Seb |
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Sollte es nicht
Delphi-Quellcode:
heissen?
constructor TOberflaeche.Create( AOwner: TComponent);
|
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? |
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:
@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.
AndereKlasse := TAndereKlasse.Create(Application);
Zitat:
|
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Kannst du den Code mal Vollständig posten?
|
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Geht das unter .NET nicht ganz anders?
|
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. |
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Hallo,
weiß nicht, ob ich mich da jetzt täusche, liegt der Hund eventuell hier begraben?
Delphi-Quellcode:
Wird im Konstruktor der TAndereKlasse der Konstruktor des Vorfahren aufgerufen? (Oder passiert das implizit? eigentlich doch nicht? oder doch oder wie oder?)
constructor TAndereKlasse.Create;
begin inherited Create; .... |
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. |
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Hallo,
so hat's bei mir funktioniert:
Delphi-Quellcode:
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.
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. Achso, das ist bestimmt kein .NET, bitte ändere den ersten Post entsprechend (wenn das geht). |
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:
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).
override;
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 |
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Application sollte ok sein.
|
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
??? Was denn nu?
Zitat:
Zitat:
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...) |
Re: Zugriffsverletzung bei Zeichnen auf Bitmap
Vielleicht solltest du den Parameter noch durchschleifen:
Delphi-Quellcode:
constructor TOberflaeche.Create(AOwner: TComponent);
begin inherited Create(AOwner); ... |
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?). |
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 02:41 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