Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Notifyevent in Komponente


rolstein - Mi 25.02.04 16:18
Titel: Notifyevent in Komponente
Hallo,

habe nach längerer Zeit wieder angefangen was mit Delphi zu machen. Nun wollte ich eine eigene Komponente erstellen (Nachfolger von TPAnel),das den Event "OnChange" enthält. Da dieser im Vorfahren nicht enthalten ist bekomme ich beim compilieren die Fehlermeldung "Methode 'Change' nicht in Basisklasse gefunden". Eigentlich klar. Wie muss ichs nun anstellen, damit ich das TNotifyEvent "OnChange" einbinden kann?

danke
rolstein


Delete - Mi 25.02.04 18:48


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type TMeineKlasse = class(TPanel)
 private
  ...
  FOnChange:TNotifyEvent;
 public
  ...
  procedure OnChangeAufrufen;
 published
  property OnChange:TNotifyEvent read FOnChange write FOnChange;
end;



Procedure TMeineKlasse.OnChangeAufrufen;
begin
 If Assigned(FOnChange) then FOnChange(self);
end;



Aufrufen musst du's dann aber selber im richtigen Moment, da es eine Procedure Change selber nicht gibt.


rolstein - Mi 25.02.04 21:31

Hallo Brainiac,

danke erst mal für die Antwort. In etwa hatte ich das Ganze so gemacht wie dus beschrieben hast. Das Problem war wohl, dass der Name 'Change' im Notifyevent bereits vorhanden ist. Nach Umbennen lässt sich die Komponente compilieren. Allerdings hat die Komponente keine Wirkung. Das hast du wohl mit deinem Kommentar 'Aufrufen musst du's dann aber selber im richtigen Moment, da es eine Procedure Change selber nicht gibt.' gemeint. Hast Du noch einen Tipp?

danke Rolstein


Delete - Mi 25.02.04 22:45

Prinzipiell nicht.
Auf die Weise kannst du allgemein Events erstellen, die du dann aus deinem Code heraus aufrufen kannst.
So funktionieren die Events in Delphi-eigenen Komponenten auch. Der gespeicherte Prozeduraufruf muss immer irgendwo im Code aufgerufen werden. Schließlich gibt es ja sowas wie ein 'Ereignis' im Computer gar nicht wirklich, sondern einfach nur einen Aufruf einer Prozedur, der halt an einer bestimmten Stelle im Code verankert ist, zum Beispiel in der Procedure, die ausgeführt wird, die neuen Text anzeigt werden soll.

Ein Event nachträglich an eine bestimmte Procedure einer früheren Klasse zu hängen ist prinzipiell unmöglich, ohne deren Code zu ändern.
Wenn die Procedure mit 'virtual' deklariert wurde, kannst du sie bestenfalls mit 'override' überschreiben und den Aufruf praktisch hinten dranhängen.


Was du damit meintest, dass 'Change' schon vorhanden war, ist mir noch nicht ganz klar.


rolstein - Do 26.02.04 16:16

Hallo Brainiac,

hab mir alles noch mal genau angeschaut. Meinen Kommentar zu 'Change' kannst Du vergessen, war nonsens.
Mein Problem war weiterhin wie ich die 'OnChange' Methode aufrufen kann. Das hab ich jetzt über eine Timerkomponente gelöst, die ich im Constructor erzeuge. Ein weiteres Property nimmt den Inhalt von Caption für den späteren Vergleich auf. der Timer ruft dann die 'OnChange' Prozedur auf. Dort wird vor auslösen des Events zunächst noch geprüft ob sich der Inhalt von Caption geändert hat (Komponente prüft zurzeit nur Caption auf Änderung).
Funktioniert zwar, ist aber irgendwie noch nicht das Ware. Werde mir noch mal überlegen, wie man das eleganter lösen kann.

dis dann
rolstein


maximus - Do 26.02.04 16:48

Hi.

Die timer lösung scheint mir die schlechteste von allen möglichen :wink: ...wenn du zB. die WM_SETTEXT message abfängst, dann hast du genau das was du willst, nämlich, wenn ichs richtig verstanden habe den zeitpunkt an dem die caption gesetzt wird:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
// oben in deiner compo
...
procedure WMSetText(var Message: TMessage); message WM_SETTEXT;
...

// in der implemtation

procedure TDeineCompo.WMSetText(var Message: TMessage);
begin
 inherited;  
 //ShowMessage(caption);
 If Assigned(FOnChange) then FOnChange(self); 

end;


Damit benutzt du gleich die windows infrastruktur und wirst sofort benachrichtigt wenn sich die caption ändert!


Delete - Do 26.02.04 19:28

Ja stimmt, nach sowas hab ich auch gesucht, aber ich kannte die richtige Message nicht.
Ist natürlich die beste Lösung!


rolstein - Fr 27.02.04 08:50

Hallo maximus,

Es ist ganz einfach, wenn man weiß wie es geht.
Super, das war genau was ich gesucht hatte.

danke
rolstein