lucamar,
with your latest code the compiler complains at line 15:
Error: Incompatible type for arg no. 1: Got "TControl", expected "TWinControl"
I think there is an inherent incompatibilty due to the recursive nature of your algorithm. That may be not trivial to resolve. Could you try to compile it on your system?
No incompatibility, just plain human error: I changed the function to accept a TWinControl so, of course, one can't pass a TControl to it

Just change those lines to:
if TWinControl(Ctrl).ControlCount > 0 then
Result := GetFocusedControl(Ctrl as TWinControl);
By now that code has had so many iterations that it's become plain ugly, what with all those type-casts. if I were to use it I would expend a couple minutes making a new, more elegant function.
Edited to add:
Ok, new,
tested code:
function GetFocusedControl(const Root: TWinControl): TWinControl;
var
i: Integer;
Ctrl: TWinControl;
begin
Result := Nil;
if Assigned(Root) and (Root.ControlCount > 0) then begin
for i := 0 to Root.ControlCount-1 do begin
if Root.Controls[i].InheritsFrom(TWinControl) then
Ctrl := Root.Controls[i] as TWinControl;
if Ctrl.Focused then
Result := Ctrl
else
if Ctrl.ControlCount > 0 then
Result := GetFocusedControl(Ctrl);
if Assigned(Result) then Break;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
AControl: TWinControl;
begin
AControl := GetFocusedControl(Self);
if Assigned(AControl) then
ShowMessageFmt('Focusesed control %s (a %s) has TabOrder: %d',
[AControl.Name, AControl.ClassName, AControl.TabOrder])
else
ShowMessage('No control seems to be focused!?');
end;