Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Ereignisse selbstdefinieren?


Stauch - Do 12.12.02 09:07
Titel: Ereignisse selbstdefinieren?
Ich habe eine neue Klasse definiert und möchte dieser Klasse ein Ereignis zuweisen, auf das sie reagieren soll. Ist das möglich? :?:

MfG
C.


smiegel - Do 12.12.02 09:55

Hallo,

klar geht das. Folgendermaßen:

// -----

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:
type
  // selbst deklariertes Ereignis
  TMyNotification=procedure(Sender:TObject; x, y:Integer) of object;

  TMyObj=class
  private
     fMyNotification:TMyNotification;
     procedure DoMyNotification(x, y:Integer); virtual;
  public
     procedure TuIrgendwas;
  published
     // Ereignis öffentlich machen
     OnMyNotification:TMyNotification read fMyNotification write fMyNotification;
end; // TMyObj


procedure TMyObj.DoMyNotification(x, y:Integer);
begin
  if Assigned(fMyNotification) then fMyNotification(Self, x, y);
end; // TMyObj.DoMyNotification

procedure TMyObj.TuIrgendwas;
var x, y:Integer;
begin
  ...
  ...
  for x:=1 to 10 do
    for y:=1 to 5 do
       DoMyNotification(x, y);
  ...
  ...
end; // TMyObj.TuIrgendwas

end;

Ich hoffe das kleine Beispiel hilft ein wenig.


Stauch - Do 12.12.02 10:17

:shock: uups.
Ich wurschtl mich mal durch. Danke auf jeden Fall

C.


Stauch - Do 12.12.02 14:03

Hallo, ich bins noch mal

der Published -Teil

Quelltext
1:
2:
3:
published 
     // Ereignis öffentlich machen 
     OnMyNotification:TMyNotification read fMyNotification write fMyNotification;

liefert Fehler:
Zitat:
OnMyNotification ist weder vom Typ class noch Interface

:roll: Was könnte da schief gelauefen sein?

C.


Jack Falworth - Do 12.12.02 14:56

Stauch hat folgendes geschrieben:

der Published -Teil

Quelltext
1:
2:
3:
published 
     // Ereignis öffentlich machen 
     OnMyNotification:TMyNotification read fMyNotification write fMyNotification;


liefert Fehler:
OnMyNotification ist weder vom Typ class noch Interface

C.


jep du musst statt "puplished" "property" hinschreiben (property = Eigenschaft)
also:


Quelltext
1:
2:
property 
OnMyNotification:TMyNotification read fMyNotification write  fMyNotification;


MfG

Jack Falworth


smiegel - Do 12.12.02 15:47

Hallo,

das mit dem published-Teil ist schon soweit richtig.
Du musst nur vor OnMyNotification property schreiben.
Sorry, war ein Fehler von mir. Das kommt davon, wenn man die Beispiele ungetestet on the fly hinschreibt.


Stauch - Fr 13.12.02 09:40

Okay, soweit geht das. D.h. es liefert keine Fehlermeldung :D

Ich habe jetzt noch ein Verständnisproblem, wie und an welcher Stelle ich das konkrete Ereignis definiere (Ich brauche ein Objekt-über-anderem- Objekt- Ereignis)

MfG

C.


Stauch - Fr 13.12.02 09:40

Okay, soweit geht das. D.h. es liefert keine Fehlermeldung :D

Ich habe jetzt noch ein Verständnisproblem, wie und an welcher Stelle ich das konkrete Ereignis definiere (Ich brauche ein Objekt-über-anderem- Objekt- Ereignis)

MfG

C.


smiegel - Mo 16.12.02 10:54

Hallo,

sorry, ich verstehe Deine Frage bzw. das Problem nicht. Kannst Du Dich da 'mal präziser ausdrücken?


Stauch - Mo 16.12.02 11:38

Ich versuche es. Ich habe ein Objekt, (Ball:TShape), das über die Form bewegt wird (durch ein Timer-Objekt). Dann habe ich mehrerer Objekte meiner neuen Klasse (class(TShape)) . Jetzt möchte ich, das diese Objekte reagieren,wenn sich Ball darüber bewegt. Also ein Ereignis z.B. onBallOver festlegen und diesem eine passende Routine zuordnen.

Und da stehe ich im Wald. Muß ich die Prozedur doMyNotification anpassen? oder die TuIrgendwas?
Mir ist nicht ganz klar, welche Prozedur welche aufgaben übernimmt.

MfG
C.


smiegel - Mo 16.12.02 12:43

Hallo,

der von mir gepostete Code sollte nur als Beispiel dienen, wie man eigene Ereignisse deklariert.

Zu Deinem Problem:
Wäre es nicht besser, die Abmessungen der TShape-Klassen in einer Liste oder array zu merken?
Da Du den Ball eh über einen Timer bewegst, kannst Du dann nach jeder Bewegung testen, ob sich der Ball über einem Element befindet.


Stauch - Mo 16.12.02 13:16

Hallo

[quote]
der von mir gepostete Code sollte nur als Beispiel dienen, wie man eigene Ereignisse deklariert[/quote]

Das ist klar, ich hab eben Probleme bei der Anpassung.

Die Überprüfung in der TimerProzedur habe ich auch in betracht gezogen
aber 1.) wollte ich die TimerProzedur nicht überfrachten, 2.) dachte ich, mit einer Ereignisdeklaration wäre es eleganter und 3.) wollte ich es eben einfach mal ausprobieren

MfG
C.


smiegel - Mo 16.12.02 13:35

Hallo Stacuh,

was Du willst, geht in Richtung Drag und Drop - viel Spass dabei ;-)


Stauch - Mo 16.12.02 14:07

:o Ja, das könnte gehen ...
Noch mal Danke. Spaß werde ich ganz sicher haben ... :!:

C.


Stauch - Do 19.12.02 13:44

Irgendwas mache ich immer noch falsch :(

Ich kann zwar ein Drag-Ereignis auslösen, aber kein Drop
Ein Timer bewegt eine Tshape Objekt über die Form. Wenn es über ein TZiegel Objekt kommt, so dieses Unsichtbar werden. Dazu will ich ein DragDrop-Ereignis ohne Verendung der Maus auslösen.
Hier der code

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:
TZiegel = class(TShape)
     procedure Init(x,y:integer);
     private
     
     fDragOver : TDragOverEvent;
     fDragDrop : TDragDropEvent;
     Procedure doDragOver(Sender, Source: TObject; X, Y: Integer;
                                State: TDragState; var Accept: Boolean);virtual;
     procedure doDragDrop(Sender, Source: TObject; X, Y: Integer);virtual;
 published property OnDragOver: TDragOverEvent read fDragOver write FDragOver;
     published property OnDragDrop: TDragDropEvent read fdragDrop write fDragDrop;
     end;
...

Procedure TZiegel.doDragOver(Sender, Source: TObject; X, Y: Integer;
                                 State: TDragState; var Accept: Boolean);
begin
 accept:=Source is TShape;
 
end;

Procedure TZiegel.doDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
 (sender as Tziegel).visible:=false;
end;

Eine TimerProzedur führt BeginDrag und EndDrag aus, aber wie gesagt, die "Drop" werden nicht ausgeführt.

Für Hilfe wäre ich sehr dankbar
MfG
C.Stauch


smiegel - Do 19.12.02 15:12

Hallo,

versuche es einmal mit DragMode:=dmAutomatic.

Außerdem darfst Du Ereignisse nicht mehr veröffentlichen, weil Sie ja schon Bestandteil des Vaterobjekts TShape sind.

Nehme also aus Deiner Deklaration

Quelltext
1:
2:
3:
4:
  fDragOver
  fDragDrop
  doDragOver
  doDragDrop

heraus.