Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Funktionsaufrufe des Parents vom Child.
muzy - Mi 28.10.09 18:32
Titel: Funktionsaufrufe des Parents vom Child.
Heyho,
die Überschrift ist vlt. etwas verwirrend jedoch hab ich ein kleines Problem.
Ich habe eine Klasse welches ein Objekt instanziert. Dieses Objekt soll nun eine Funktion des Objektes aufrufen welches das Objekt instanziert hat.
Beispiel: Spielfeld instanziet Objekte der Klasse Spielkarte. Diese Spielkarte soll nun eine Funktion "foo" des Spielfeldes aufrufen. Hat da jemand ne Idee wie das gehen kann?
LG
Muzy
Moderiert von
Narses: Topic aus Sonstiges (Delphi) verschoben am Mi 28.10.2009 um 17:53
Boldar - Mi 28.10.09 18:34
ich könnte mir höchstens messages vorstellen, oder das Childobjekt muss bei der erstellung ein pointer auf den parent mitkriegen.
muzy - Mi 28.10.09 18:37
Irgendwie muss das gehen, unsere Lehrerin hat uns das so vorgegeben.
Wir übergeben beim Instanzieren Allerdings einen "Aowner" vom Typ Tcomponent, und setzen diesen AOwner vom Typ TComponent auch als Parent.
Vielleicht hilft das als Info weiter.
Critter - Mi 28.10.09 18:42
Hi,
naja warum greifst du dann nicht über
Parent daraf zu:
Delphi-Quelltext
1: 2:
| if (parent is tSpielfeld) then tSpielfeld(parent).foo; |
Immer vorrausgesetzt, das tSpielfeld auch als Parent von tSpielKarte ist.
critter
thepaine91 - Mi 28.10.09 18:42
Was für ein Objekt denn? Objekt ist ziemlich dehnbar.
muzy - Mi 28.10.09 18:45
Dieses tSpielfeld(parent).foo geht nicht, da bekomme ich einen udnefinierten Bezeichner.
Erwähnenswert ist das ich mit Delphi 6 arbeiten muss.
self.parent.foo geht ebenfalls nicht -- auch ein Undefinierter Bezeichner.
Xentar - Mi 28.10.09 18:47
nud was genau ist undefiniert?
elundril - Mi 28.10.09 18:48
wie wärs mit
Delphi-Quelltext
1: 2:
| if (Parent is TSpielfeld) then (Parent as TSpielfeld).foo(); |
lg elundril
muzy - Mi 28.10.09 18:50
Der Bezeichner "foo" ist undefiniert.
Hier mal die Sourcen:
Spielfeld:
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: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159:
| unit mSpielfeld;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, mKarte; type
TSpielfeld = class protected
private hPunktestand,zeilen,spalten,curzeile,curspalte,curleft,curtop,anzkarten: integer; kartenmischer: array[1..24] of integer; kartenarray: array[1..48] of TKarte;
public
constructor Create(AOwner: TComponent;pAnzkarten:Integer); virtual; destructor destroy; procedure setPunktestand(pPunktestand: integer); function getPunktestand: integer; procedure ZeigeFeld (AOwner: TComponent); function Mischen: integer; procedure ZeilenSpaltenHelfer; procedure SetzeZeilenSpalten; procedure foo;
end;
implementation
constructor TSpielfeld.Create(AOwner: TComponent;pAnzKarten:Integer); var i:integer; begin inherited create; curtop := 50; curleft := 8; curzeile := 1; curspalte := 1;
anzkarten := pAnzKarten; ZeilenSpaltenHelfer; for i:= 1 to anzkarten do begin kartenarray[i] := TKarte.create(AOwner, Mischen); kartenarray[i].Name := 'Karte' + InttoStr(i); kartenarray[i].Height := 100; kartenarray[i].Width := 100; kartenarray[i].left := curleft; kartenarray[i].top := curtop; kartenarray[i].Parent := (AOwner as TWinControl); SetzeZeilenSpalten;
end;
end;
procedure TSpielFeld.foo; begin
showmessage('foo');
end;
procedure TSpielFeld.SetzeZeilenSpalten; begin if curspalte = spalten then begin curspalte := 1; curzeile := curzeile +1; end else begin curspalte := curspalte +1; end; case curzeile of 1: curtop := 50; 2: curtop := 152; 3: curtop := 254; 4: curtop := 356; 5: curtop := 458; 6: curtop := 560; end; case curspalte of 1: curleft := 8; 2: curleft := 110; 3: curleft := 212; 4: curleft := 314; 5: curleft := 416; 6: curleft := 518; 7: curleft := 620; end; end;
procedure TSpielFeld.ZeilenSpaltenHelfer; begin case anzkarten of 4:begin zeilen:=2;spalten:=2; end; 6:begin zeilen:=2;spalten:=3; end; 8:begin zeilen:=2;spalten:=4; end; 10:begin zeilen:=3;spalten:=4; end; 12:begin zeilen:=3;spalten:=4; end; 16:begin zeilen:=4;spalten:=4; end; end; end;
function TSpielFeld.Mischen:integer; var tmp,success,res,randzahl:integer; begin success := 0; randzahl := round(anzkarten / 2); while success = 0 do begin tmp := random(randzahl)+1; if (kartenmischer[tmp] < 2) and (tmp <> 0) and (tmp <= randzahl) then begin success := 1; res := tmp; kartenmischer[tmp] := kartenmischer[tmp] +1; end; end; result := res; end;
procedure TSpielFeld.ZeigeFeld (AOwner: TComponent); var i:integer; begin for i:=1 to anzkarten do begin kartenarray[i].Visible:=true; end; end;
destructor TSpielfeld.destroy; var i:integer; begin inherited destroy; for i:=1 to anzkarten do begin kartenarray[i].destroy; end; end;
procedure TSpielfeld.setPunktestand(pPunktestand: integer); begin end;
function TSpielfeld.getPunktestand: integer; begin end; end. |
Karte:
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: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
| unit mKarte;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type
TKarte = class(TImage) procedure BeiClick (Sender: TObject); private hWert: integer; zVerdeckt: Boolean;
public constructor create(AOwner: TComponent; pWert: integer); virtual; destructor destroy; procedure setWert (pWert: integer); function getWert: integer; procedure setVerdeckt (pVerdeckt: Boolean); function getVerdeckt: Boolean; end;
implementation
constructor TKarte.create (AOwner: TComponent; pWert: integer); begin inherited Create (AOwner); self.Picture.LoadFromFile('rueck.bmp'); self.OnClick := BeiClick; self.Visible := False; zVerdeckt := True; hWert := pWert; end;
procedure TKarte.BeiClick (Sender: TObject); begin if zVerdeckt then begin self.Picture.LoadFromFile(IntToStr(self.hWert) + '.bmp'); zVerdeckt := not zVerdeckt; end;
end;
destructor TKarte.destroy; begin inherited destroy; end;
procedure TKarte.setWert(pWert: integer); begin hWert:=pWert; end;
function TKarte.getWert: integer; begin result := hWert; end;
procedure TKarte.setVerdeckt (pVerdeckt: Boolean); begin zVerdeckt := pVerdeckt; end;
function TKarte.getVerdeckt: Boolean; begin result := zVerdeckt; end;
end. |
Ich verstehe einfach nicht warum das nicht so simpel geht :/
Btw, alle eure Ideen geben den undefinierten Bezeichner aus. Der meint immer "foo" ist undefiniert.
Moderiert von
Narses: Code aus den Links eingefügt.
elundril - Mi 28.10.09 18:52
foo() ist eine beispielprocedure. da wir nicht wissen was für eine procedure ausführen willst, schreiben wir einfach foo() hin. also, ersetze foo() durch den namen deiner Procedure und fertig. gegebenenfalls noch die parameter anpassen. ;)
lg elundril
muzy - Mi 28.10.09 18:53
Oehm, es gibt die Funktion TSpielfeld.foo ;)
elundril - Mi 28.10.09 18:54
aso, wusst ich nicht...
hast du den namen der unit in der TSpielfeld ist ins uses von der Unit in der TKarte drin ist reingeschrieben?
lg elundril
HelgeLange - Mi 28.10.09 18:55
Du musst schaun, dass Spielfeld bekannt ist, wenn Du den Parent drauf castest. Also unit einbinden zum Bsp.
Auch solltest Du nicht den parent nehmen, sondern den Owner. Parent ist für Zeichnen von WinControls verantwortlich, Owner ist der Besitzer des Objects. Also wenn dein Spielfeld die Karte erstellt mit
MeineKarte := TSpielKarte.Create(Self);
dann ist der owner ganz sicher dein Spielfeld.
muzy - Mi 28.10.09 18:56
das geht nicht da sich das sonst überkreuzt. TSpielfeld hat sinnvollerweise die Karte (TKarte) drinnen, in TKarte kann ich allerdings nicht das Spielfeld in die uses schreiben, alles schon probiert.
---
Moderiert von
Narses: Beiträge zusammengefasst---
und self.Owner.foo funktioniert ebenfalls auch nicht :(
Xentar - Mi 28.10.09 18:58
muzy hat folgendes geschrieben : |
das geht nicht da sich das sonst überkreuzt. TSpielfeld hat sinnvollerweise die Karte (TKarte) drinnen, in TKarte kann ich allerdings nicht das Spielfeld in die uses schreiben, alles schon probiert. |
Klar, in die Uses unter Implementation.
Aber warum machst du für sowas nicht ein neues Ereignis?
Critter - Mi 28.10.09 18:59
muzy hat folgendes geschrieben : |
und self.Owner.foo funktioniert ebenfalls auch nicht :( |
Hi, da musst du auch wieder auf tSpielfeld Casten
also
tSpielFeld(Owner).foo;.
critter
muzy - Mi 28.10.09 19:00
Wenn cih ehrlich bin hab ich keine Ahnung,
wie in den Sourcen hab ich halt, bzw hat jede Karte ein BeiClick Ereignis, dieses soll dem Spielfeld mitteilen das es geklickt wurde. Sprich es muss eine Funktion des Spielfeldes aufrufen.
muzy - Mi 28.10.09 19:02
Ah nachdem ich im Implementation Teil (und nciht im Interface Teil) ein eigenes "uses" einbaute hat es geklappt. Kann mir wer erklären was dieses Uses im Implementation Teil von dem im Interface Teil unterscheidet?
martin300 - Mi 28.10.09 19:05
muzy hat folgendes geschrieben : |
Heyho,
Beispiel: Spielfeld instanziet Objekte der Klasse Spielkarte. Diese Spielkarte soll nun eine Funktion "foo" des Spielfeldes aufrufen. Hat da jemand ne Idee wie das gehen kann?
Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Mi 28.10.2009 um 17:53 |
Im Prinzip kann alles vom Spielfeld aus zugegriffen werden. Dort ist auch ein Array mit den 48 Karten gespeichert.
muzy - Mi 28.10.09 19:10
Danke Elundril, (und all den anderen natürlich auch)
nur das mit den Uses im Implementation Teil ist mir noch gänzlich neu -- hat man uns wohl versäumt beizubringen. Aber ich werd das nochmal genau nachlesen. Auf jeden Fall schonmal vielen Dank für eure Hilfe
HelgeLange - Do 29.10.09 02:07
Aber warum nimmst Du dann nicht events ?
Du definierst ein OnClick event (wenn nicht schon da) bei der Karte und hängst das Ereignis im Spielfeld an diesen event handler.
thepaine91 - Do 29.10.09 09:27
Das wäre noch besser ;)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!