Autor |
Beitrag |
FinnO
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: 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
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.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: 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
      
Beiträge: 764
Erhaltene Danke: 127
|
Verfasst: 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
Delphi-Quelltext
oder so heißen, Du übergibst ja nicht das Image.
ub60
|
|
FinnO 
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: 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...
Delphi-Quelltext 1:
| FZielCanvas : TCanvas; |
Gesetzt wird das ganze so:
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
Delphi-Quelltext 1:
| FZielCanvas.LineTo(X,Y); |
und so weiter.
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Do 12.03.09 22:07
FinnO hat folgendes geschrieben : | 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 
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: 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
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: 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
      
Beiträge: 764
Erhaltene Danke: 127
|
Verfasst: Do 12.03.09 23:39
FinnO hat folgendes geschrieben : | 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 
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Fr 13.03.09 19:14
soo ich hab das mal wie UB gesagt hat (bzw. wie ich es verstanden habe) gemacht...
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 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); end; |
Wodran liegts?
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Fr 13.03.09 19:23
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 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); 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.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Fr 13.03.09 19:24
Zuletzt bearbeitet von Marc. am Fr 13.03.09 19:29, insgesamt 1-mal bearbeitet
|
|
FinnO 
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Fr 13.03.09 19:25
@ elundril: negativ
@Marc. + Elundril: Kombiniert klappts, beim Beenden kriege ich noch folgende Exception:
"Externe Exception"
|
|
ub60
      
Beiträge: 764
Erhaltene Danke: 127
|
Verfasst: Fr 13.03.09 20:22
Was ich meinte, geht etwa so:
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(100, 150, 50); Z.Free; end; |
ub60
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Fr 13.03.09 21:03
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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. ub60 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:
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(100, 150, 50); finally Zeichner.Free; end; end; |
|
|
FinnO 
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Sa 14.03.09 00:23
hmm also ersteres war klar ^^
zweiteres Wusste ich gar nicht
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
:closed:
|
|