![]() |
Re: "inherited" für umgeleitetes Event
Zitat:
Zitat:
Du erzeugst jedesmal solch eienn Eventhandler:
Delphi-Quellcode:
Aber du gibst schlussendlich nur einen frei!
procedure InitClickEventRetouring(Ctrl: TObject);
begin MyEventReceiver := TMyEventReceiver.Create; // <- "Knackpunkt" ! { ... } end;
Delphi-Quellcode:
Da musst du dir was anderes einfallen lassen, z.b. eine Liste mit Eventhandlern oder ähnliches....
finalization
MyEventReceiver.Free; So der nächste wichtige Punkt, du überprüfst nicht ob es vorher überhaupt ein Event gab!
Delphi-Quellcode:
Das solltest du ändern in:
procedure TMyEventReceiver.ClickIntern(Sender: TObject);
begin { ... } OnClickOrig(Sender); end;
Delphi-Quellcode:
Sprich du schaust erstmal ob der Methodenzeichner belegt wurde, bevor du ihn ausführst...
procedure TMyEventReceiver.ClickIntern(Sender: TObject);
begin { ... } If Assigned( OnClickOrig ) Then OnClickOrig(Sender); end; Als leztes nur eine kleine Anmerkung:
Delphi-Quellcode:
Hier solltest du eventuell nachschaun, ob Ctrl überhaupt ein Wert hat! Aber viel wichtiger, udem kann da ein Wert übergeben werden, der gar keine OnClick Ereigniss hat, bzw. schon gar nicht ein TButton ist!
procedure InitClickEventRetouring(Ctrl: TObject);
begin {...} TButton(Ctrl).OnClick := MyEventReceiver.ClickIntern; end; Da gehört also sowas hin wie:
Delphi-Quellcode:
das wärs erstmal von meinen Anmerkungen....
procedure InitClickEventRetouring(Ctrl: TObject);
begin {...} If Assigned( Ctrl ) And ( Ctrl Is TButton ) Then TButton(Ctrl).OnClick := MyEventReceiver.ClickIntern; end; Bye Christian |
Re: "inherited" für umgeleitetes Event
Zitat:
Zitat:
Zitat:
Zitat:
Das ist ein sehr wichtiger Punkt, denn darum geht es in diesem Thread ja: Es soll ein (Click-)Event abgefangen und zurückgeleitet werden, falls auch was zum Zurückleiten da ist. Denn sonst könnte ich ja einfach im Original-(Click-)Event meinen ausgelagerten Code aufrufen. Der ausgelagete Code soll aber auch ausgeführt werden, wenn im Form garkein (Click-)Event existiert. Zitat:
Ein TypeCasting "(Ctrl as TButton).OnClick := ..." wirft ja bei Fehlern eine Exception während "TButton(Ctrl).OnClick := ..." gutmütig über ein übergebenes Label hinwegsieht. Das war schonmal mein Ansatz, den Code für mehrere Control-Typen benutzen zu können. Ich hätte es aber gerne noch sauberer! Gruß, Guido. |
Re: "inherited" für umgeleitetes Event
Zitat:
Zitat:
Delphi-Quellcode:
ich schrieb weiter oben schonmal woher das Onlick kommt! Nimm statt TObject ein TControl...
procedure InitClickEventRetouring(Ctrl: TObject);
begin {...} If Assigned( Ctrl ) And ( Ctrl Is TButton ) Then TButton(Ctrl).OnClick := MyEventReceiver.ClickIntern; end; Desweiteren hättest du die möglichkeit explezit nach den Klassen zu schauen ungefär so:
Delphi-Quellcode:
Procedure InitClickEventRetouring( Ctrl: TControl );
Begin If ( Ctrl Is TButton ) Then Begin // Mach was mit dem TButton End Else If ( Ctrl Is TLabel ) Then Begin // Mach was mit dem TLabel End Else If ( Ctrl Is TPanel ) Then Begin // Mach was mit dem TPanel End Else Begin // tja is was anderes, mach halt was anderes... End; End; Bye Christian |
Re: "inherited" für umgeleitetes Event
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Delphi-Quellcode:
unit Unit2;
interface procedure InitClickEventRetouring(Ctrl: TObject); implementation uses Dialogs, Classes, StdCtrls, Contnrs; type TClickEvnt = procedure (Sender: TObject) of object; TMyEventReceiver = class private FClickOrig: TClickEvnt; procedure ClickIntern(Sender: TObject); public property OnClickOrig: TClickEvnt read FClickOrig write FClickOrig; end; var EvRecvList: TObjectList; procedure TMyEventReceiver.ClickIntern(Sender: TObject); begin ShowMessage('Umgeleitetes Event von: ' + TButton(Sender).Name); If (Assigned(OnClickOrig)) Then OnClickOrig(Sender); end; procedure InitClickEventRetouring(Ctrl: TObject); var MyEventReceiver: TMyEventReceiver; begin try MyEventReceiver := TMyEventReceiver.Create; MyEventReceiver.OnClickOrig := TButton(Ctrl).OnClick; TButton(Ctrl).OnClick := MyEventReceiver.ClickIntern; EvRecvList.Add(MyEventReceiver); except ShowMessage('Error in ClickEventRetouring code'); end; end; initialization EvRecvList := TObjectList.Create; finalization EvRecvList.Free; end. Zitat:
Zitat:
Gruß, Guido. |
Re: "inherited" für umgeleitetes Event
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zitat:
Desweiteren hast du noch eine unstimmigkeit in deinem Code!
Delphi-Quellcode:
Du hast zwar einen Try..Except Block, aber das Object steht im Fehlerfall sicher nicht in der Liste und wird schlussendlich nicht freigegeben!
procedure InitClickEventRetouring(Ctrl: TObject);
var MyEventReceiver: TMyEventReceiver; begin try MyEventReceiver := TMyEventReceiver.Create; MyEventReceiver.OnClickOrig := TButton(Ctrl).OnClick; TButton(Ctrl).OnClick := MyEventReceiver.ClickIntern; EvRecvList.Add(MyEventReceiver); except ShowMessage('Error in ClickEventRetouring code'); end; end; Du solltest es gleich nach dem Erzeugen in die Liste packen.... Eventuell ist es auch sinvoller den ursprünglichen Fehlercode nach außen zu geben! ich hab das mal alles umgebaut... so sieht meine Lösung aus:
Delphi-Quellcode:
BTW: Wenn du sowieso am testen bist, es gibt sicher auch eine Möglichkeit über die RTTI...
Procedure InitClickEventRetouring( Ctrl: TControl );
Var MyEventReceiver: TMyEventReceiver; Begin If Assigned( Ctrl ) Then Begin // Wenn kein Object pbergeben wurde können wir uns gleich alles sparen... MyEventReceiver := TMyEventReceiver.Create; // Receiver erzeugen... EvRecvList.Add( MyEventReceiver ); // Receiver gleich in die Liste einfügen, damit es nicht verloren geht... Try If ( Ctrl Is TButton ) Then Begin // Es ist ein TButton MyEventReceiver.OnClickOrig := TButton( Ctrl ).OnClick; TButton( Ctrl ).OnClick := MyEventReceiver.ClickIntern; End Else If ( Ctrl Is TLabel ) Then Begin // Es ist ein TLabel MyEventReceiver.OnClickOrig := TLabel( Ctrl ).OnClick; TLabel( Ctrl ).OnClick := MyEventReceiver.ClickIntern; End Else If ( Ctrl Is TPanel ) Then Begin // Es ist ein TPanel MyEventReceiver.OnClickOrig := TPanel( Ctrl ).OnClick; TPanel( Ctrl ).OnClick := MyEventReceiver.ClickIntern; End Else Begin // Es ist ein was anderes, aber da wir mit einem TControl arbeiten, Casten wir einfach auf TButton ;=) MyEventReceiver.OnClickOrig := TButton( Ctrl ).OnClick; TButton( Ctrl ).OnClick := MyEventReceiver.ClickIntern; End; Except On Error: Exception Do Begin // Jeder Fehler ist eine Exception... ShowMessage( 'Error in ClickEventRetouring code: "' + Error.Message + '"' ); // zusätzlich geben wir den Fehler mit aus! End; End; End; End; Du könntest dort in der Tabelle anch dem "OnClick" Property suchen und es dann benutzen, falls vorhanden... Aber das wird alles nicht super schnell sein... Ich würd das wenn, nur im letzten Else Block bei mir machen, um wirklich sicher zu sein, dass da was ist... Ev. macht es dann auch sinn mit einem TObject zu arbeiten... Bye Christian |
Re: "inherited" für umgeleitetes Event
Hallo Christian.
Die letzen beiden Tage war ich sehr beschäftigt und bin noch nicht dazu gekommen zu antworten. Sorry dafür. Zitat:
Zitat:
Zitat:
Deine an sich schon gute Routine habe ich so übernommen, habe mich aber dazu entschlossen bei einem Fehler die EventReceiver-Instanz garnicht erst in die Liste aufzunhemen.
Delphi-Quellcode:
procedure InitClickEventRetouring(Ctrl: TControl);
var MyEventReceiver: TMyEventReceiver; begin if Assigned(Ctrl) then // wurde ein Objekt übergeben ? begin MyEventReceiver := nil; try MyEventReceiver := TMyEventReceiver.Create; MyEventReceiver.OnClickOrig := TButton(Ctrl).OnClick; TButton(Ctrl).OnClick := MyEventReceiver.ClickIntern; except On Error: Exception Do // Bei allen Fehlern den Speicher begin // freigeben und Nachricht ausgeben. // MyEventReceiver.Free; FreeAndNil(MyEventReceiver); ShowMessage('Error in ClickEventRetouring code with message:' + #13#10 + #13#10 + '"' + Error.Message + '"'); end; end; // nur in Liste einfügen, wenn kein Fehler aufgetreten ist if (Assigned(MyEventReceiver)) then EvRecvList.Add(MyEventReceiver); end; end; Zitat:
Danke für deine Unterstützung! Gruß, Guido. Edit: TObject durch TControl ersetzt und "Free" durch "FreeAndNil" ersetzt. |
Re: "inherited" für umgeleitetes Event
Autsch :cyclops:
Deine If-Abfrage:
Delphi-Quellcode:
Wird bei einem Fehler dein Freigegebenes Objekt trotzdem aufnehmen...
if (Assigned(MyEventReceiver)) then EvRecvList.Add(MyEventReceiver);
Delphi-Quellcode:
Zerstört nähmlich nur das Objekt und setzt es nicht Nil, was du aber mit Assigned abfragst...
MyEventReceiver.Free;
Nimm stattdesen:
Delphi-Quellcode:
;)
FreeAndNil( MyEventReceiver )
Nunja Zerstören musst du das Object ja eh, ob du das nun im Exvept Teil machst oder am Programmende ;) Bye Christian |
Re: "inherited" für umgeleitetes Event
Zitat:
Zitat:
Ciao, Guido. |
Re: "inherited" für umgeleitetes Event
So sieht das alles sauber aus. Ich denke so können wir den Code auf die öffentlichkeit loslassen :zwinker:
Ich hoffe du hast ein wenig was gelernt :party: Bye Christian |
Re: "inherited" für umgeleitetes Event
Ein kleiner "Schriebfheler" hat sich eingeschlichen: Überall im Code/Posting wo "Retouring" steht, sollte das durch "Rerouting" ersetzt werden. :warn: :-D
@Christian. Gelernt dabei: einiges. Dank dafür: vielen! :cheers: Ciao, Guido. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz