program KbLangLED;

uses
  Windows;


type
  TKbLEDTag = (kbledNum, kbledCaps, kbledScroll);

procedure ToggleKeybrdLED(LEDTag: TKbLEDTag);

  procedure SimulateLkKey(KeyDown: Boolean);
  const
    VKeyCodes: array[TKbLEDTag] of Byte = (VK_NUMLOCK, VK_CAPITAL, VK_SCROLL);
    ScanCodes: array[TKbLEDTag] of Byte = ($45, $3A, $46);
  begin
    keybd_event(VKeyCodes[LEDTag], ScanCodes[LEDTag], KEYEVENTF_EXTENDEDKEY +
      Ord(not KeyDown) * KEYEVENTF_KEYUP, 0);
  end;

begin
  SimulateLkKey(True);
  SimulateLkKey(False);
end;


const
  LangKbLED = kbledScroll;  // LED to indicate language

var
  Mutex: THandle;
  EnUS: Boolean;
  OldEnUS: Boolean = True;
  Msg: TMsg;

begin
  // Check already running
  Mutex := CreateMutex(nil, True, 'KbLangLED_Running');
  if WaitForSingleObject(Mutex, 0) <> WAIT_OBJECT_0 then
    Exit;

  // Turn off the feedback cursor
  if PostThreadMessage(GetCurrentThreadId, 0, 0, 0) then
    GetMessage(Msg, 0, 0, 0);

  while True do
  begin
    EnUS := GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow)) and
      $FFFF = $0409;
    if EnUS <> OldEnUS then
    begin
      ToggleKeybrdLED(LangKbLED);
      OldEnUS := EnUS;
    end;
    Sleep(100);
  end;
end.
