This is an excerpt from my Delphi generics-based unit Zoomicon.Collections:
uses System.Rtti; //for RttiContext
//...
type
TListEx<T> = class(TList<T>)
//...
{ForEach}
class procedure ForEach(const Enum: TEnumerable<T>; const Proc: TProc<T>; const Predicate: TPredicate<T> = nil); overload;
procedure ForEach(const Proc: TProc<T>; const Predicate: TPredicate<T> = nil); overload;
end;
//...
{$region 'ForEach'}
class procedure TListEx<T>.ForEach(const Enum: TEnumerable<T>; const Proc: TProc<T>; const Predicate: TPredicate<T> = nil);
begin
if Assigned(Proc) then
for var item in Enum do
if (not Assigned(Predicate)) or Predicate(item) then
Proc(item);
end;
procedure TListEx<T>.ForEach(const Proc: TProc<T>; const Predicate: TPredicate<T> = nil);
begin
{TListEx<T>.}ForEach(self, Proc, Predicate);
end;
{$endregion}
try using with anonymous methods so that you can capture context and pass to the TProc that you pass as a reference (since that only accepts T). See below how to pass DX, DY for example:
type
Manipulator = class(TFrame)
pubic
class procedure MoveControls(const Controls: TControlList; const DX, DY: Single); overload;
procedure MoveControls(const DX, DY: Single); overload;
end;
class procedure TManipulator.MoveControls(const Controls: TControlList; const DX, DY: Single);
begin
if (DX <> 0) or (DY <> 0) then
TListEx<TControl>.ForEach(Controls,
procedure (Control: TControl)
begin
with Control.Position do
Point := Point + TPointF.Create(DX, DY);
end
);
end;
procedure TManipulator.MoveControls(const DX, DY: Single);
begin
if (DX <> 0) or (DY <> 0) then
begin
BeginUpdate;
MoveControls(Controls, DX, DY);
EndUpdate;
end;
end;
myManipulator.MoveControls(20, 20);
You can find more advanced versions though there that can also cast items from collections to the class you need:
TObjectListEx<TControl>.ForEachClass<TButton>(Controls, SomeProc);
which is an optimization (since it doesn't construct an intermediate list) compared to doing something like:
var list := TObjectListEx<TControl>.GetAllClass<TButton>(Controls);
list.ForEach(SomeProc);
FreeAndNil(list);
Currently at the repository of an App I'm developing:
https://github.com/Zoomicon/READCOM_App/tree/master/Zoomicon.Generics/Collections (will probably move to its own repository in the future)