Zitat von
Guido Eisenbeis:
Leider führt TControl sein OnClick nicht nach außen! Es ist protected.
Das mag war sein, aber die Speicherstelle von OnClick sollte sich nicht verändern... Heißt du kannst auf TButton oder TPanel casten und kommst zum protected OnClick-Event... (aber das ist unsauber!...
Zitat von
Guido Eisenbeis:
Das wäre auch meine "Notlösung".
Nunja, das ist die einzig wahre, um erhlich zu sein...
Desweiteren hast du noch eine unstimmigkeit in deinem Code!
Delphi-Quellcode:
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 hast zwar einen Try..Except Block, aber das Object steht im Fehlerfall sicher nicht in der Liste und wird schlussendlich nicht freigegeben!
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:
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;
BTW: Wenn du sowieso am testen bist, es gibt sicher auch eine Möglichkeit über die
RTTI...
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