Stefan Glienke hat gestern noch ein wenig Hand angelegt und ich möchte euch das Ergebnis nicht vorenthalten:
Zitat von
Stevie:
hab mal deinen control enumerator umgeschrieben, um jegliche allokationen zu vermeiden und alle methoden inlinen zu lassen
Delphi-Quellcode:
type
TWinControlHelper = class helper for TWinControl
type
TControlEnumerator<T: TControl> = record
private
FIndex, FCount: Integer;
FWinControl: TWinControl;
FCurrent: T;
public
function MoveNext: Boolean; inline;
property Current: T read FCurrent;
end;
TControls<T: TControl> = record
private
FWinControl: TWinControl;
public
function GetEnumerator: TControlEnumerator<T>; inline;
end;
public
function ControlsOf<T: TControl>: TControls<T>; inline;
end;
{ TWinControlHelper }
function TWinControlHelper.ControlsOf<T>: TControls<T>;
begin
Result.FWinControl := Self;
end;
{ TWinControlHelper.TControls<T> }
function TWinControlHelper.TControls<T>.GetEnumerator: TControlEnumerator<T>;
begin
Result.FIndex := 0;
Result.FWinControl := FWinControl;
Result.FCount := FWinControl.ControlCount;
end;
function TWinControlHelper.TControlEnumerator<T>.MoveNext: Boolean;
var
LControl: TControl;
begin
repeat
if FIndex < FCount then
begin
LControl := FWinControl.Controls[FIndex];
Inc(FIndex);
if LControl.InheritsFrom(T) then
begin
FCurrent := T(LControl);
Exit(True);
end;
end
else
Exit(False)
until False;
end;
Wie sieht es denn bei folgender Konstellation aus?
Delphi-Quellcode:
for i := 0 to ComponentCount-1 do
if Components[i] is TButton then
TButton(Components[i]).Caption := 'Hello World'
else
if Components[i] is TPageControl then
TPageControl(Components[i]).ActivePageIndex := 0
else
if Components[i] is TEdit then
TEdit(Components[i]).Font.Style := [fsBold];
Man bräuchte dann ja 3 Durchläufe, anstatt, wie im Beispiel zusehen, nur einen Durchlauf.