Autor Beitrag
muzy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mi 28.10.09 18:32 
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 user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 28.10.2009 um 17:53
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 328
Erhaltene Danke: 3

Windows 7
Delphi 7 Pro.
BeitragVerfasst: Mi 28.10.09 18:42 
Hi,

naja warum greifst du dann nicht über Parent daraf zu:

ausblenden Delphi-Quelltext
1:
2:
if (parent is tSpielfeld) then
  tSpielfeld(parent).foo;


Immer vorrausgesetzt, das tSpielfeld auch als Parent von tSpielKarte ist.

critter

_________________
Diejenigen, die grundlegende Freiheiten aufgeben, um ein wenig mehr vorrübergehende Sicherheit zu erkaufen, verdienen weder Freiheit noch Sicherheit.
(Benjamin Franklin;"The Papers of Benjamin Franklin", Vol. 6, Apr. 1, 1755, through Sep. 30, 1756)
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Mi 28.10.09 18:42 
Was für ein Objekt denn? Objekt ist ziemlich dehnbar.
muzy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Mi 28.10.09 18:47 
nud was genau ist undefiniert?

_________________
PROGRAMMER: A device for converting coffee into software.
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: Mi 28.10.09 18:48 
wie wärs mit

ausblenden Delphi-Quelltext
1:
2:
if (Parent is TSpielfeld) then
  (Parent as TSpielfeld).foo();


lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
muzy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mi 28.10.09 18:50 
Der Bezeichner "foo" ist undefiniert.

Hier mal die Sourcen:

Spielfeld:
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:
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..24of integer;  //maximal 48 Karten
   kartenarray: array[1..48of 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// Wird benutzt zum lustigen Kartensetzen ;)
 curleft := 8// s.o.
 curzeile := 1;
 curspalte := 1;

 anzkarten := pAnzKarten; // Muss durch 2 Teilbar sein empfohlene Werte: [8,16]
 ZeilenSpaltenHelfer;   // Zur weiteren Initialisierung

 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:=2end;
         6:begin zeilen:=2;spalten:=3end;
         8:begin zeilen:=2;spalten:=4end;
        10:begin zeilen:=3;spalten:=4end;
        12:begin zeilen:=3;spalten:=4end;
        16:begin zeilen:=4;spalten:=4end;
      //  20:begin zeilen:=5;spalten:=4; end;
      //  24:begin zeilen:=6;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] < 2and (tmp <> 0and (tmp <= randzahl) then  // error handling
    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:
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:
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); // Selbstdefinierte onClick-Methode

  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;

 // HIER FOO METHODE VOM PARENT (SPIELFELD)

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 user profile iconNarses: Code aus den Links eingefügt.
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: 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

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
muzy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mi 28.10.09 18:53 
Oehm, es gibt die Funktion TSpielfeld.foo ;)
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: 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

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

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: 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);  // self ist das Spielfeld

dann ist der owner ganz sicher dein Spielfeld.

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
muzy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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 user profile iconNarses: Beiträge zusammengefasst---

und self.Owner.foo funktioniert ebenfalls auch nicht :(
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: Mi 28.10.09 18:58 
user profile iconmuzy hat folgendes geschrieben Zum zitierten Posting springen:
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?

_________________
PROGRAMMER: A device for converting coffee into software.
Critter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 328
Erhaltene Danke: 3

Windows 7
Delphi 7 Pro.
BeitragVerfasst: Mi 28.10.09 18:59 
user profile iconmuzy hat folgendes geschrieben Zum zitierten Posting springen:
und self.Owner.foo funktioniert ebenfalls auch nicht :(

Hi, da musst du auch wieder auf tSpielfeld Casten

also tSpielFeld(Owner).foo;.

critter

_________________
Diejenigen, die grundlegende Freiheiten aufgeben, um ein wenig mehr vorrübergehende Sicherheit zu erkaufen, verdienen weder Freiheit noch Sicherheit.
(Benjamin Franklin;"The Papers of Benjamin Franklin", Vol. 6, Apr. 1, 1755, through Sep. 30, 1756)
muzy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Mi 28.10.09 19:05 
user profile iconmuzy hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconNarses: 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.
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: Mi 28.10.09 19:06 
darf ich dir Christian's Crashkurs empfehlen Muzy? Ich denke, es wäre hilfreich für dich!

lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.