Autor Beitrag
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Do 12.03.09 19:19 
Hi Community,

Im Informatikunterricht programmieren ein Kumpel und ich gerade eine neue, für unsere Zwecke verbesserte Turtle-Komponente.

Dazu würden wir gerne das Canvas, auf das gezeichnet werden soll variabel machen. Leider hagelt es bei ungefähr folgendem Code dauernd Zugriffsverletzungen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
...
property ZielCanvas : TCanvas read GetCanvas write Setcanvas;
...
begin
  ZielCanvas := Image.Canvas;
end;


begin
  ZielCanvas.doSth
end;


muss man das evtl. Anders angehen?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Do 12.03.09 19:55 
Ich fürchte, Hilfe wird hier schwer fallen. Du hast nicht gesagt, welche Fehler gemeldet werden und der Quelltext erscheint völlig aus dem Zusammenhang gerissen und entscheidende Teile (z.B. Getter- und Setter-Methoden) fehlen.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Do 12.03.09 20:08 
Bei dem geringen Quelltext nur eine Vermutung.
Also zuerst einmal, man kann´die Canvas zuweisen. Irgendwie sollte es dann aber
ausblenden Delphi-Quelltext
1:
Zielcanvas=FCanvas					

oder so heißen, Du übergibst ja nicht das Image.

ub60
FinnO Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Do 12.03.09 21:59 
Sorry, ich kann den Code aus der Schule leider nicht mehr wortwörtlich aber im Groben ist das so aufgebaut:

ich glaube, das canvas war eine Field...
ausblenden Delphi-Quelltext
1:
  FZielCanvas : TCanvas;					


Gesetzt wird das ganze so:

ausblenden Delphi-Quelltext
1:
  FZielCanvas := Image1.Canvas					


Die Idee dahinter ist, dass nun die Änderungen die wir an der ZielCanvas vornehmen sich auf die Image1.Canvas auswirken.

(ich glaube hier haben wir einen Denkfehler gemacht, muss man da mit Pointern o.ä. Arbeiten? Oder mit Handles (KP), weil ich glaube, so wie es momentan ist, werden die Änderungen nur in der ZielCanvas geändert nicht aber auf der eigentlich zu benutzenden Canvas Image1.Canvas?)

der Versuch zu Zeichnen ist dann
ausblenden Delphi-Quelltext
1:
 FZielCanvas.LineTo(X,Y);					


und so weiter.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 12.03.09 22:07 
user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
  FZielCanvas := Image1.Canvas					

Was ist Image1? Wo wird das gesetzt? Und warum glaubst du, dass die Änderungen an FZielCanvas durchgeführt werden? Ein Canvas alleine ist nichts - du kannst ihn nicht einfach erzeugen, also muss er wohl der zugewiesene sein. Andernfalls würde eine Exception ausgelöst werden.
FinnO Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Do 12.03.09 22:12 
image1 ist eine ganz normale Komponente vom Typ TImage auf dem Formular...

Ich habe mittlerweile die Vermutung wir liegen sowas von falsch, dass ich lieber einfach mal unseren Code vergesse und die Frage in den Raum werf:

Angenommen, ich möchte ein beliebiges Bild auf irgendein beliebiges Canvas zeichnen, wie gehe ich das an? Dabei muss beachtet werden, dass ich Das Canvas variable zuweisen möchte und nicht Hardcoden.
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Do 12.03.09 22:45 
Ähm.. versteh ich das richtig:
Du hast eine Klasse erstellt. In dieser Klasse möchtest du ein Canvas verwenden?
Warum greifst du dann doch wieder auf ein bestimmtes Canvas, nämlich in diesem Fall Image1.Canvas zu..?

Normalerweise geht man doch so vor, dass man beim instanziieren dieser Klasse das Canvas VON AUSSEN reinreicht, und nicht, dass sich die Klasse das selber holt?
Edit: Dafür ist ja normalerweise auch das Property, dass du bereits angelegt hast.. zeig mal mehr Code.

_________________
PROGRAMMER: A device for converting coffee into software.
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Do 12.03.09 23:39 
user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
Die Idee dahinter ist, dass nun die Änderungen die wir an der ZielCanvas vornehmen sich auf die Image1.Canvas auswirken.
(ich glaube hier haben wir einen Denkfehler gemacht, muss man da mit Pointern o.ä. Arbeiten?

Weder noch. Die Idee ist i.O., die übergebene Canvas ist nichts anderes als ein Zeiger.
Zum Vorgehen ein Beispiel:
  • Ich möchte eine Figur als Klasse erstellen, deren Objekte man auf jeder Canvas zeichnen kann.
  • Also erstelle ich in der Klasse ein Attribut FCanvas. Auf dieser Canvas führe ich alle Zeichenoperationen durch.
  • Mit einer SetCanvas-Methode teile ich meinem Objekt (vor dem ersten Zeichnen) mit, auf welcher Canvas es gezeichnet werden soll.

ub60
FinnO Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Fr 13.03.09 19:14 
soo ich hab das mal wie UB gesagt hat (bzw. wie ich es verstanden habe) gemacht...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
type
  TZeichnen = Class

    procedure SetCanvas(Canvas : TCanvas);
    function  GetCanvas : TCanvas;
    
    property FCanvas read GetCanvas write SetCanvas;
  end;

implementation

{$R *.dfm}

procedure TZeichnen.SetCanvas(Canvas : TCanvas);
begin
  FCanvas := Canvas // Reicht das hier???
end;

procedure TZeichnen.GetCanvas : TCanvas
begin
  result := FCanvas;
end;

procedure TForm1.Form1Create(Sender : TObject);
var
  Z : TZeichnen;
begin
  Z.FCanvas.Ellipse(100,100,200,200); // Zugriffsverletzung
end;


Wodran liegts?
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Fr 13.03.09 19:23 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
type
  TZeichnen = Class
  private
    FCanvas: TCanvas
  public
      procedure SetCanvas(Canvas : TCanvas);
          function  GetCanvas : TCanvas;
  published   
      property Canvas read GetCanvas write SetCanvas;
  end;

implementation

{$R *.dfm}

procedure TZeichnen.SetCanvas(Canvas : TCanvas);
begin
  FCanvas := Canvas // Reicht das hier???
end;

procedure TZeichnen.GetCanvas : TCanvas
begin
  result := FCanvas;
end;

procedure TForm1.Form1Create(Sender : TObject);
var
  Z : TZeichnen;
begin
  Z := TZeichnen.Create;
  Z.Canvas := TForm1.Canvas;
  Z.Canvas.Ellipse(100,100,200,200); // Zugriffsverletzung
end;


so sollte es schon eher funktionieren denke ich.

lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Fr 13.03.09 19:24 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.Form1Create(Sender : TObject);
var
  Z : TZeichnen;
begin
  Z.SetCanvas(...);
  Z.FCanvas.Ellipse(100,100,200,200);
end;


IMHO solltest du auch die Setter Methode aufrufen, bevor du auf ein nicht referenziertes Canvas zugreifst. ;)


Zuletzt bearbeitet von Marc. am Fr 13.03.09 19:29, insgesamt 1-mal bearbeitet
FinnO Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Fr 13.03.09 19:25 
@ elundril: negativ :(

@Marc. + Elundril: Kombiniert klappts, beim Beenden kriege ich noch folgende Exception:

"Externe Exception"
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Fr 13.03.09 20:22 
Was ich meinte, geht etwa so:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
type
  TZeichnen = Class
    protected
      FCanvas : TCanvas;
    public
      procedure SetCanvas(Canvas : TCanvas);
      procedure ZeichneKreis(x,y,r:Integer);
      function  GetCanvas : TCanvas;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TZeichnen.GetCanvas: TCanvas;
begin
  Result:=FCanvas;
end;

procedure TZeichnen.SetCanvas(Canvas : TCanvas);
begin
  FCanvas := Canvas;
end;

procedure TZeichnen.ZeichneKreis(x,y,r:Integer);
begin
  FCanvas.Ellipse(x-r, y-r, x+r, y+r);
end;

procedure TForm1.FormCreate(Sender : TObject);
var Z : TZeichnen;
begin
  Z:=TZeichnen.Create;
  Z.SetCanvas(Image1.Canvas);
  Z.ZeichneKreis(10015050);
  Z.Free;
end;

ub60
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Fr 13.03.09 21:03 
user profile iconub60 hat folgendes geschrieben Zum zitierten Posting springen:
Was ich meinte, geht etwa so:
ausblenden Delphi-Quelltext
1:
2:
3:
    public
      procedure SetCanvas(Canvas : TCanvas);
      function  GetCanvas : TCanvas;


Genau das macht doch ein Property - nur eben als eine Eigenschaft.

_________________
PROGRAMMER: A device for converting coffee into software.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Fr 13.03.09 22:02 
Äh, jetzt nochmal im Klartext: Die Zugirffsverletzung kam, weil das Objekt Z (übrigens ein sehr gut gewählter Bezeichner für eine Zeichenklasse ;)) nicht initialisiert wurde. user profile iconub60 hat die fehlende Zeile in seinem Code eingeführt.

Aber so, wie die Klasse bis jetzt definiert ist, könnte man noch einiges rausschmeißen:



ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
type
  TZeichnen = class
  private
    fCanvas: TCanvas;
  public
    procedure ZeichneKreis(x, y, r: Integer);

    property Canvas: TCanvas read fCanvas write fCanvas;
  end;

implementation

procedure TZeichnen.ZeichneKreis(x, y, r: Integer);
begin
  fCanvas.Ellipse(x-r, y-r, x+r, y+r);
end;

procedure TForm1.FormCreate(Sender : TObject);
var Zeichner : TZeichnen;
begin
  Zeichner := TZeichnen.Create;
  try
    Zeichner.SetCanvas(Image1.Canvas);
    Zeichner.ZeichneKreis(10015050);
  finally
    Zeichner.Free;
  end;
end;
FinnO Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Sa 14.03.09 00:23 
hmm also ersteres war klar ^^

zweiteres Wusste ich gar nicht :oops:

aber jetzt ist alles Klärchen... danke


Ich geb euch doch nicht den Code von meiner Turtle ;) da muss schon mal ne Zeichenklasse Z zur verdeutlichung herhalten :evil:

:closed: