Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Ereignis einer zur Laufzeit erstellten Klasse
Schatten^parker - Sa 14.09.02 18:31
Titel: Ereignis einer zur Laufzeit erstellten Klasse
Hi Leute ich hab ein Problem.
Ich habe eine Klasse Timage geschaffen die zur laufzeit erstellt wird. Jedoch kann man somit keine Ereignisse in die Images Implementieren.
Meine Frage nun, wie kann ich einer klasse ein onclick Ereignis zuordnen.
und wie sendet mir diese komponente ihren namen zurück.
danke
LCS - Sa 14.09.02 18:49
Hi
Hast du nun eine neue Klasse erstellt (dann wäre TImage ein denkbar schlechter Name) oder hast du ein Objekt vom Typ TImage in deinem Programm erzeugt?
Ich geh mal einfach vom zweiten aus. Dann musst du natürlich deine Ereignisprozeduren auch zur Laufzeit zuweisen. Die Prozedur brauchst du natürlich erst mal:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| type TForm1 = class(TForm) ... procedure ImgClick(Sender: TObject); ... ...
procedure TForm1.ImgClick(Sender: TObject); begin ... end; |
Wenn du dein Objekt erstellt hast, kannst du diese Prozedur zuweisen
Quelltext
1: 2: 3:
| ... MeinErstelltesImage.OnClick := ImgClick; ... |
Den Namen eines Objekts liefert die Eigenschaft
Name. So du nach dem Erstellen überhaupt einen zugewiesen hast.
Gruss Lothar
Schatten^parker - So 15.09.02 13:49
Titel: naja weiss nicht .....
TKarte = class(TImage)
somit habe ich eine klasse Timage erstellt die proceduren und so'n zeugs beinhaltet
jetzt werden aber zur laufzeit Objekte der Klasse(Timage) erschaffen deren namen ich nicht festlege, nur Position auf dem Formular und Bildquelle werden festgelegt. Und ich moechte das wenn man auf ein Image klickt eine Procedure aufgerufen wird, also durch ein Ereignis.
Vielleicht kannst du dir besser Vorstellen wenn du weisst das es ein Memmory Spiel werden soll bei dem alle Karten zur Laufzeit erzeugt werden.
DeCodeGuru - So 15.09.02 14:16
Ich habe es jetzt zwar nicht so ganz verstanden. Nehmen wir an, du erstellt deine Objekte (is ja egal ob TImage oder irgendeine abgeleitete Klasse) in einem Array. Also in etwa so:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var i: Integer; ImageArray: array [0..9] of TImage; begin for i := 0 to 9 do begin ImageArray[i] := TImage.Create; with ImageArray[i] do begin ... //Hier Position und sowas angeben. Im Moment uninteressant end; end; end; |
Wenn du jetzt auf ein Bildchen klickst so zum Beispiel folgende Prozedure ausgelöst werden:
Quelltext
1: 2: 3: 4:
| procedure TForm.DoClick(Sender: TObject); begin ShowMessage('Klick'); end; |
Damit diese Prozedur ausgelöst wird, musst du das OnClick-Ereignis, der erstellten Objekte mit der Prozedure verknüpfen. Dazu nehmen wird den ersten Code und fügen etwas hinzu:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| var i: Integer; ImageArray: array [0..9] of TImage; begin for i := 0 to 9 do begin ImageArray[i] := TImage.Create; with ImageArray[i] do begin ... //Und hier wieder die Posangaben und was weiss ich nicht alles OnClick := DoClick; end; end; end; |
Damit du aber die Images unterscheiden kannst, also, damit du unterscheiden kannst auf welches Image jetzt geklickt wurde, würde ich denen Namen vergeben. Das könnte man so machen (den Code anstelle des '...' einfügen):
Somit hast du den Images einen eindeutigen Namen zugewiesen. Damit kannst du auch in der DoClick-Prozedure die Images unterscheiden.
Ich hoffe, ich konnte dir ein bisschen helfen bzw. dir die Sache verdeutlichen :wink:
Schatten^parker - So 15.09.02 20:56
Das ist ja alles ganz toll mit den array und so aber ich möchte das ohne sie machen. Ich moechte den Karte der Klasse Timage auch keine namen zuweisen.
Ich moechte lediglich eine Ereignisprocedure implementieren die beim klick auf die Images aufgerufen wird. Da die Images zur laufzeit erschaffen werden kann ich ihnen über den Objektinspektor keine Ereignisse zuteilen.
hier ist mal der code (newbie code also nicht lachen), vielleicht wisst ihr dann besser was ich moechte.
Der Code ist noch nicht lauffähig und die Erschaffung der Karten ist noch umständlich aber dieses Problem behebe ich später.....
Wie gesagt es handelt sich um ein MemmorySpiel, soll es jedenfalls mal werden.... DANKE!!!!!!!!!
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, extctrls;
type TKarte = class(TImage) private
bildname : string; public
procedure bildladen; procedure karteverdecken; procedure Karteaufdecken; Procedure Vergleichen; Procedure Punktezuweisen; Procedure Kartenloeschen;
end;
type TFrm_Memmory = class(TForm) T_vergleichen: TTimer; procedure FormCreate(Sender: TObject); procedure T_vergleichenTimer(Sender: TObject);
private karte1,karte2,karte3 : Tkarte; { Private-Deklarationen } public
{ Public-Deklarationen } end;
var Frm_Memmory: TFrm_Memmory; karte: Tkarte;
implementation
procedure TKarte.bildladen; begin self.Picture.LoadFromFile(self.bildname);
end;
procedure TKarte.karteverdecken; begin self.visible:=false; end;
procedure Tkarte.Karteaufdecken; begin self.Visible:= true; end;
Procedure tkarte.Vergleichen; begin
end;
Procedure tkarte.Punktezuweisen; begin If KARTE1.picture = KARTE2.Picture then do begin punktezuweisen; Kartenloeschen; end else tfrm_memmory.T_vergleichen.enabled:= false;
end;
{$R *.DFM} procedure TFrm_Memmory.FormCreate(Sender: TObject); begin karte1 := tkarte.Create(self); karte1.Parent := self; karte1.bildname := 'bilder\karte1.bmp'; karte1.bildladen; karte2 := tkarte.Create(self); karte2.Parent := self; karte2.bildname := 'bilder\karte1.bmp'; karte2.bildladen; karte2.Left := 100; karte3 := tkarte.Create(self); karte3.Parent := self; karte3.bildname := 'bilder\karte2.bmp'; karte3.bildladen; karte3.Left := 200; end;
procedure TFrm_Memmory.T_vergleichenTimer(Sender: TObject); begin KARTE1.Visible:= False; KARTE2.Visible:= False; T_vergleichen.enabled:= false; end;
end. |
Tino - So 15.09.02 21:45
Schatten^parker hat folgendes geschrieben: |
Ich moechte lediglich eine Ereignisprocedure implementieren die beim klick auf die Images aufgerufen wird. |
Wie das geht hat LCS schon gepostet:
Quelltext
1:
| MeinErstelltesImage.OnClick := ImgClick; |
Außerdem hat es DeCodeGuru nochmals erklärt:
Gruß
TINO
Schatten^parker - Mo 16.09.02 12:08
HarHarHar, es hat funktioniert, danke nochmal an alle
Schatten^parker - Mo 16.09.02 18:56
Hab noch ne Frage, wenn ich nun auf die Karte Klicke, moechte ich dass mir der name der Karte zurückgeliefert oder in einer variablen gespeichert wird.
Wie die Karten erzeugt werden könnt ihr oben in meinem Quelltext nachlesen,
ist zwar etwas umständlich aber für den moment soll das so bleiben.
aogwaba - Mo 16.09.02 20:50
Hi!
Quelltext
1: 2: 3: 4: 5: 6:
| var KartenName:string;
procedure TFrm_Memmory .Karte_wurde_angeklickt(sender:TObject); begin if sender is TKarte then KartenName:=sender.name; end; |
cu
waba
LCS - Di 17.09.02 07:52
Hi
kleine Korrektur:
Quelltext
1: 2: 3: 4: 5: 6:
| var KartenName:string;
procedure TFrm_Memmory .Karte_wurde_angeklickt(sender:TObject); begin if sender is TKarte then KartenName:=TKarte(sender).name; end; |
Sender ist ja als TObject deklariert und die gibts keine Eigenschaft Name.
Aber: Wenn du einen Namen willst, musst du deinen Objekten beim Erstellen erst mal nen Namen verpassen. Wurde weiter oben schon von DeCodeGuru beschrieben. Wenn du keine Arrays verwenden willst:
Quelltext
1: 2: 3: 4: 5:
| ... karte2 := tkarte.Create(self); karte2.Parent := self; karte2.Name := 'Karte2'; ... |
Gruss Lothar
aogwaba - Di 17.09.02 15:31
Hi!
Nee, das ist schon richtig. Für das Vorhandensein des Name-Property sorgt ja der Vorgänger der TKarte->TImage. 'is' checkt ja die Instanz des Object's nicht die des Typ's.
Quelltext
1: 2: 3:
| var myObject:TObject; myObject:=TImage.create(self); if (myObject is timage) then ... |
cu
waba
LCS - Di 17.09.02 18:33
Hi
Zitat: |
Für das Vorhandensein des Name-Property sorgt ja der Vorgänger der TKarte->TImage.
|
Nix dagegen einzuwenden. Trotzdem wird es ja zunächst mal vom Typ TObject übergeben. Die Eigenschaft Name ist zwar vorhanden, aber du kannst sie erst ansprechen, wenn du TObject wieder in TKarte castet. Versuchst du direkt Sender.Name ergibt das:
Zitat: |
[Fehler] Unit1.pas(31): Undefinierter Bezeichner: 'Name'
|
Gruss Lothar
aogwaba - Di 17.09.02 19:04
Hi!
Hast recht, der Typcst fehlt:
Quelltext
1:
| if sender is TKarte then KartenName:=(sender as TKarte).name; |
cu
waba
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!