unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    txtInterval: TEdit;
    cmbStart: TButton;
    Timer1: TTimer;
    procedure cmbStartClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

var
  initCaps, initNum, initScroll: Boolean; //Первоначальные состояния клавиш
  curCaps, curNum, curScroll: Boolean;    //Текущие состояния клавиш

{$R *.dfm}

//Процедура имитирует нажатие на кливишу с переданным кодом
procedure PressKey(keyCode: Byte);
begin
  keybd_event(keyCode, 0, 0, 0 );
  keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0 );
end;

procedure TForm1.cmbStartClick(Sender: TObject);
begin
  if cmbStart.Caption = 'Старт' then
  begin
    //Сохраняем первоначальные состояния клавиш
    initCaps := (GetKeyState(VK_CAPITAL) and 1) <> 0;
    initNum := (GetKeyState(VK_NUMLOCK) and 1) <> 0;
    initScroll := (GetKeyState(VK_SCROLL) and 1) <> 0;
    //Включаем только CapsLock
    if not initCaps then PressKey(VK_CAPITAL);
    curCaps := True;
    if initNum then PressKey(VK_NUMLOCK);
    curNum := False;
    if initScroll then PressKey(VK_SCROLL);
    curScroll := False;
    //Запускаем "бегущие огни"
    Timer1.Interval := StrToInt(txtInterval.Text);
    Timer1.Enabled := True;
    cmbStart.Caption := 'Стоп';
  end
  else
  begin
    //Останавливаем "бегущие огни"
    Timer1.Enabled := False;
    cmbStart.Caption := 'Старт';
    //Восстанавливаем первоначальные состояния клавиш
    if initCaps <> curCaps then PressKey(VK_CAPITAL);
    if initNum <> curNum then PressKey(VK_NUMLOCK);
    if initScroll <> curScroll then PressKey(VK_SCROLL);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //Изменяем состояние лампочек на клавиатуре
  if curCaps then
  begin
    //С CapsLock на NumLock
    PressKey(VK_NUMLOCK);
    PressKey(VK_CAPITAL);
    curCaps := False;
    curNum := True;
  end
  else if curNum then
  begin
    //С NumLock на ScrollLock
    PressKey(VK_SCROLL);
    PressKey(VK_NUMLOCK);
    curNum := False;
    curScroll := True;
  end
  else
  begin
    //С ScrollLock на CapsLock
    PressKey(VK_CAPITAL);
    PressKey(VK_SCROLL);
    curScroll := False;
    curCaps := True;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Timer1.Enabled then
    //Останавливаем огни
    cmbStartClick(nil);
end;

end.
