Ich fange in einigen Komponenten gerne Ereignisse anderer Komponenten ein ('capture events') und speichere dabei einen Zeiger auf eine evt schon zugewiesene Ereignisroutine, damit diese nicht 'abgehängt' wird, sondern in der 'untergeschobenen' Routine ebenfalls mit aufgerufen werden kann. Das sieht in etwa so aus:
Delphi-Quellcode:
procedure TADOPosManager.UpdateLinks;
{inline compare:}
function IsSameEvent(E1, E2: TDatasetNotifyEvent): boolean;
type
TEventPointer = record
case Integer of
1: (E: TDatasetNotifyEvent);
2: (P: Pointer);
end;
var P1, P2: TEventPointer;
begin
P1.E := E1;
P2.E := E2;
Result := (P1.P = P2.P);
end;
begin
if (FTable <> nil) then
begin
with FTable do
begin
if not IsSameEvent(OnNewRecord,DoOnNewRecord) then
FOrgOnNewRecord := OnNewRecord;
OnNewRecord := DoOnNewRecord;
end;
end
else ...
Und die Ereignisroutine selbst etwa so:
Delphi-Quellcode:
procedure TADOPosManager.DoOnNewRecord(ADataset: TDataset);
begin
ADataset.FieldByName(FFieldName).AsInteger := FNewNr;
if Assigned(FOrgOnNewRecord) then
FOrgOnNewRecord(ADataSet);
end;
Durch 'IsSameEvent' bei der Zuweisung kann ich sicherstellen, daß ich mir keine endlose Rekursion innerhalb ein und derselben Komponente einfange (mit dem unvermeidlichen 'stack overflow') - aber wie sieht das aus, wenn ich mehrere Komponenten mit derselben Technik einsetze und vermeiden will, daß die eine jeweils die 'untergeschobene' Routine der anderen als 'Original' betrachtet? Kann ich irgendwie feststellen, wem eine bereits zugewiesene Routine 'gehört' (also zB einem Form oder Frame - oder eben einer anderen Komponente)? Bei einem einfachen wechselseitigen Aufruf würde auch helfen, die Adresse (den Zeiger) der aufrufenden Routine mit der (dem) der aufzurufenden Routine zu vergleichen, aber das schützt schon nicht mehr vor einer drei- oder mehrfachen Rekursionschleife.
Oder hat jemand bessere Vorschläge? Oder ist die ganze Vorgehensweise einfach 'Mist' und Rekursionen lassen sich nicht zuverlässig vermeiden...?
peinhard
[edit=r_kerber]code- durch delphi-Tags ersetzt. Mfg, r_kerber[/edit]