Ich finde Mattzes Ansinnen, Fragestellung, Argumenation und Vorgehensweise absolut ok. Dieses 'völlig sinnfreie Anliegen' ist ein sehr wichtiger Bestandteil einer für viele vermutlich komplett überflüssigen Tätigkeit, die unsere Gesellschaft zwar weiterbringt ('Fortschritt'), aber jedoch im eigentlichen Sinne unproduktiv und für Laien teilweise auch blödsinnig ist.
Diese offensichtlich für Einige bekloppte Tätigkeit nennt sich:
Forschen und basiert in erster Linie auf
Wissensdurst. Und dieser Durst nach Wissen kann nur gestillt werden, wenn Vorbehalte ("
Das braucht man doch nicht", "
Geht auch anders", "
völlig Sinnfrei") mal außen vor gelassen werden. Diese Vorbehalte kommen in der
Anwendung zum Einsatz (und sind Antrieb von so etwas wie
Wirtschaftlichkeit), haben in der
Forschung jedoch nichts zu suchen.
Für Einige scheint
Forschung und
Programmieren nichts miteinander zu tun zu haben.
Zum Thema: Endllosschleifen in ereignisgesteuerten Programmabläufen lassen sich zuverlässig über Markierungen vermeiden. Grundsätzlich geht da so:
Delphi-Quellcode:
Procedure MyEventHandler(SomeObject : TSomeObject);
Begin
If IsHandled[SomeObject] then exit;
IsHandled[SomeObject] := true;
Try
DoSomeThingWith(SomeObject); // <<< Löst das Ereignis 'MyEvent' erneut aus
Finally
IsHandled[SomeObject] := false;
End
End;
Eine andere Vorgehensweise ist die, einen die Schleife auslösenden Aufruf nur dann auszuführen, wenn es unbedingt nötig ist. Ein Beispiel ist ein Grid, welches die Spaltenbreite automatisch anpasst, wenn der darzustellende Text breiter als die augenblickliche Spaltenbreite ist. Dann wird die Breite ja nur gesetzt, wenn die Spalte noch nicht breit genug war. Hier findet zwar ein rekursiver Aufruf statt, aber nach dem ersten Aufruf ist Schluss, da die Breite ja beim 2. Aufruf passt.
Delphi-Quellcode:
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
sg : TStringGrid;
begin
if not (Sender is TStringGrid) then exit;
sg := TStringGrid(Sender);
w := sg.Canvas.TextWidth(sg.Cells[aCol, aRow]);
if w>sg.ColWidths[aCol] then
sg.ColWidths[aCol] := w; // <<< löst ein erneuten Aufruf von DrawCell aus!
...
end;
Hier würde ich vermutlich den zweiten Ansatz nehmen, denn der Text muss ja nur verändert werden, wenn noch nicht geändert wurde.
Eigentlich ist das 2.Pattern eine Spezialisierung des 1.Patterns, denn das [Delphi]IsModified[SomeObject][/delpi] wird ja durch die Änderung des Objekts abgebildet.