[gelöst] Aufruf Ereignisroutine eines Parent vom Child

Rund um die LCL und andere Komponenten
Antworten
Helios
Lazarusforum e. V.
Beiträge: 106
Registriert: Mi 29. Jun 2011, 22:36
OS, Lazarus, FPC: Lazarus 2.2.4 Windows 10 64Bit / Lazarus 2.0.12 Debian 11.7 „Bullseye" 64Bit
CPU-Target: 64Bit
Wohnort: Leonberg

[gelöst] Aufruf Ereignisroutine eines Parent vom Child

Beitrag von Helios »

Hallo Forenmitglieder,

eine Frage zum Thema: Aufruf einer Ereignisroutine eines Parent und übermittlung Child Daten zum Parent.
Konkret:
In einer ScrollBox erzeuge ich mit einem Doppelklick dynamisch von TShape abgeleitetete Objekte (TOpticalArea)
(vgl. auch den Thread https://www.lazarusforum.de/viewtopic.php?f=18&t=12424, der mir dabei geholfen hat).
Die Eigenschaften eines TOpticalArea kann ich über ein (ebenfalls) dynamisch erzeugtes PopUpmenü (Farbe, Höhe, Breite, etc.)
mit einem Rechtsklick ändern.
Diese Funktionen sind (hoffe ich) nach der objektorientierten Lehre in dem entsprechenden Object (TOpticalArea) "gekapselt".
Um die grafischen TShape Elemente später verwalten zu können, zeige ich Diese auch in textueller Form in einem TreeView Fenster an.
Bei einem Doppelklick auf ein existierendes (grafisches) TOpticalArea soll es sowohl grafisch als auch aus dem Treeview Fenster gelöscht werden.
Das grafische Löschen funktioniert wunderbar. Leider weiss ich nicht, wie ich den Doppelklick auf das existierende TOpticalArea auf das
Parent, die ScrollBox, übermittle, damit ich von dort aus im TreeView den Eintrag der TOpticalView löschen kann.

Weiterhin möchte ich die Höhe, Breite, etc. vom TOpticalArea(=TShape) in der StatusBar anzeigen, wenn ich mit der Maus über der
entsprechenden Instanz des TOpticalArea bin.
Das ist eigentlich ein ähnliches Problem wie oben beschrieben, da ich mit einem MousEnter auf den TOpticalArea(=TShape) Informationen in ein
übergelagertes Objekt (hier die StatusBar) übertragen möchte (im Code Beispiel habe ich es direkt auf den Canvas des
TOpticalArea geschrieben, was ich eigentlich in der Statusbar sehen möchte).

Hier stoße ich an die Grenzen bzgl. meiner OOP- und Eventhandling-Kenntnisse und hoffe auf einen entsprechenden Tipp aus der
Forengemeinde.

Vielen Dank für eine Rückmeldung und schönen Abend
Arne

PS: Beispielcode nun wieder mit Lazarus 2.0.2 unter Windows 7 erstellt
Dateianhänge
OptischerKoppler.zip
(129.63 KiB) 84-mal heruntergeladen
Zuletzt geändert von Helios am Do 18. Jul 2019, 21:50, insgesamt 2-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Aufruf Ereignisroutine eines Parent vom Child

Beitrag von af0815 »

Normalerweise löse ich das mit eine´m Callback. Damit kann ich dem Parent mitteilen das sich was geänderet hat. Siehe auch http://michael-puff.de/Programmierung/A ... back.shtml
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Aufruf Ereignisroutine eines Parent vom Child

Beitrag von kupferstecher »

Das ist eigentlich genau der Einsatzzweck von Vererbung.

In der Elternklasse definierst du eine virtuelle Prozedur, in der du die gewünschten Aktionen ausführst, z.B.

Code: Alles auswählen

Type TElternKlasse = class
  Procedure DoSth(AParam: Boolean); virtual;
end;
 
implementation
Procedure TElternklasse.DoSth(AParam: Boolean);
begin
  self.setbounds(...);
end;


In der abgeleiteten überlädst du dann die Prozedur und rufst Inherited auf (und damit die Prozedur der Elternklasse).

Code: Alles auswählen

Type TKindKlasse = class(TElternKlasse)
  Procedure DoSth(AParam: Boolean); override;
end;
 
implementation
Procedure TElternklasse.DoSth(AParam: Boolean);
begin
  Inherited(AParam);
  //...
end;

Helios
Lazarusforum e. V.
Beiträge: 106
Registriert: Mi 29. Jun 2011, 22:36
OS, Lazarus, FPC: Lazarus 2.2.4 Windows 10 64Bit / Lazarus 2.0.12 Debian 11.7 „Bullseye" 64Bit
CPU-Target: 64Bit
Wohnort: Leonberg

Re: Aufruf Ereignisroutine eines Parent vom Child

Beitrag von Helios »

Hallo af0815 und kupferstecher,
vielen Dank für Eure schnelle Rückmeldung.
@kupferstecher:
Ich glaube ich habe mich falsch ausgedrückt. Das "Parent" ist die ScrollBox, in die ich meine TShapes platziere. Sie sind nicht miteinander verwandt.
Die TShapes/TOpticalAreas sind nur in dem Container "ScrollBox" erstellt worden. Weil die TShapes/TOpticalAreas so schon gekapselt sind, wird ein Doppelklick
nach der Erzeugung eines TShapes/TOpticalAreas von diesen "weggefangen" und nicht mehr an den übergeordneten Container (die ScrollBox) weitergeleitet.
Das ist eigentlich das was ich möchte: Nach dem Löschen des TShapes möchte ich der ScrollBox den weiteren Doppelklick mitteilen, damit dieser alle
weiteren Informationen des TShapes/TOpticalAreas löscht. Mit anderen Worten, das was in TFormMain.ScrollBox1DblClick dynamisch erzeugt wurde, soll
beim 2. Doppelklick auf das entsprechende TShape/TOpticalArea wieder vollständig gelöscht werden.
Ich glaube die Callback Vorgehensweise ist das, was mir hier weiterhelfen könnte, das muss ich mir in den nächsten Tagen nochmal anschauen.
Danke nochmal für Eure Hilfe und Gruß
Arne

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Aufruf Ereignisroutine eines Parent vom Child

Beitrag von fliegermichl »

Man kann den Mausklick prinzipiell an den Ereignishandler des Parents weiterleiten. Jedes Control hat ja die Eigenschaft Parent und man kann in dem OnClick Event Parent.OnClick(self) aurufen. Wenn dabei aber self freigegeben wird, fliegt dir das um die Ohren weil die Programmausführung nachher in einen Eventhandler zurückkehrt dessen Objektinstanz nicht mehr existiert.
Ich hab in solchen Fällen eine Liste "Zu_Loeschende_Objekte". Der Eventhandler des Controls macht dann nichts weiter als sich da einzutragen.

In einem Idle Event wird später geprüft, ob sich Werte in der Liste befinden und werden dann erst freigegeben.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Aufruf Ereignisroutine eines Parent vom Child

Beitrag von kupferstecher »

@Helios:
Da hab ich dich etwas missverstanden. Die Vererbung kommt erst dann zum Tragen, wenn du verschiedene Elemente plazieren möchtest.

Ansonsten ist die Callback-Methode, also eine Prozedur über eine Funktionsvariable zu übergeben, schon der richtige Weg um eine saubere Trennung der Units zu gewährleisten. Für Quick-Und-Dirty bzw. einen Erstversuch kannst du natürlich auch die Prozedur aus dem Maus-Handler raus direkt rufen.

Helios
Lazarusforum e. V.
Beiträge: 106
Registriert: Mi 29. Jun 2011, 22:36
OS, Lazarus, FPC: Lazarus 2.2.4 Windows 10 64Bit / Lazarus 2.0.12 Debian 11.7 „Bullseye" 64Bit
CPU-Target: 64Bit
Wohnort: Leonberg

Re: Aufruf Ereignisroutine eines Parent vom Child

Beitrag von Helios »

Hallo alle zusammen,
vielen Dank für eure Hilfe. Ich habe mich nun für die schon erwähnte Callback Variante entschieden. Im Anhang nun ein Beispielprogramm (funktioniert ganz gut unter Windows, unter Debian ist
der Text etwas hässlich wenn man über die erzeugten Shapes mit der Maus drüber fährt, aber den Code kann man auch unter Debian auskommentieren;-).
Da die CallBack Routine in einem Objekt verpackt ist, muss bei
TCallBackFunc = procedure(Sender: TObject) of object;
noch das "of objekt" drangehängt werden, das war eigentlich die größte Hürde beim Kompilien. Nun läuft es und die Lösung finde ich schön elegant und wiederverwendungswert, Dank eurer Tipps.

Schönen Abend noch und nochmal herzlichen Dank für euren Support und an die Lazarus/Free Pascal Entwickler.
Einfach eine saugute Sprache/Entwicklungsumgebung und sie gefällt mir immer mehr!

Gruß

Arne
Dateianhänge
ShapeDesigner.zip
(129.83 KiB) 98-mal heruntergeladen

Antworten