unit uMoveControl;

interface

uses Forms, Classes, Controls;

type
  TMoveControl = class(TObject)
   private
    CForm: TForm;
    List: TList;
   public
    procedure NextControl;
    procedure PrevControl;
    procedure FirstControl;
    procedure LastControl;

    procedure GetOrderList(OList: TStrings);
    procedure UpdateList;

    constructor Create(AForm: TForm);
    destructor Destroy;
    procedure Free;
  end;

implementation

{ TMoveControl }

constructor TMoveControl.Create(AForm: TForm);
var
   i, j, ind: integer;
begin
 List := TList.Create;

 CForm := AForm;

 CForm.GetTabOrderList(list);

 j := 0;
 for i := 0 to list.Count-1 do
  if (TWinControl(List.items[j]).CanFocus = false) or
     (TWinControl(List.items[j]).TabStop = false) or
     (TWinControl(List.items[j]).Name = '') or
     (TWinControl(List.items[j]).ClassName = 'TPanel' ) then begin
   list.delete(j);
  end else j := j + 1;
end;

procedure TMoveControl.UpdateList;
var
   i, j: integer;
begin
 List.Clear;

 CForm.GetTabOrderList(list);

 j := 0;
 for i := 0 to list.Count-1 do
  if (TWinControl(List.items[j]).CanFocus = false) or
     (TWinControl(List.items[j]).TabStop = false) or
     (TWinControl(List.items[j]).Name = '') or
     (TWinControl(List.items[j]).ClassName = 'TPanel' ) then begin
   list.delete(j);
  end else j := j + 1;
end;

destructor TMoveControl.Destroy;
begin
 List.Clear;
 List.Free;

// Self := null;
end;

procedure TMoveControl.FirstControl;
begin
 CForm.ActiveControl := TWinControl(List.items[0]);
end;

procedure TMoveControl.Free;
begin
 if Assigned(Self) then Destroy;
end;

procedure TMoveControl.GetOrderList(OList: TStrings);
var
   i: integer;
begin
 OList.Clear;

 for i := 0 to list.Count-1 do
   OList.Add(TWinControl(List.items[i]).Name);
end;

procedure TMoveControl.LastControl;
begin
 CForm.ActiveControl := TWinControl(List.items[list.Count - 1]);
end;

procedure TMoveControl.NextControl;
var
   ind: integer;
begin
 ind := list.IndexOf(CForm.ActiveControl);
 if (ind = -1) and Assigned(CForm.ActiveControl.Parent) then begin
   ind := list.IndexOf(CForm.ActiveControl.Parent);
 end;

 if ind = list.Count - 1 then ind := 0 else ind := ind + 1;

 CForm.ActiveControl := TWinControl(List.items[ind]);
end;

procedure TMoveControl.PrevControl;
var
   ind: integer;
begin
 ind := list.IndexOf(CForm.ActiveControl);
 if (ind = -1) and Assigned(CForm.ActiveControl.Parent) then begin
   ind := list.IndexOf(CForm.ActiveControl.Parent);
 end;

 if ind = 0 then ind := list.Count - 1 else ind := ind - 1;

 CForm.ActiveControl := TWinControl(List.items[ind]);

end;

end.
