bool __fastcall TOwnConsole::Input(UnicodeString & Str, bool Echo, unsigned int Timer)
{
  unsigned long PrevMode, NewMode;
  GetConsoleMode(FInput, &PrevMode);
  NewMode = PrevMode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
  if (Echo)
  {
    NewMode |= ENABLE_ECHO_INPUT;
  }
  else
  {
    NewMode &= ~ENABLE_ECHO_INPUT;
  }
  SetConsoleMode(FInput, NewMode);

  bool Result = false;

  try
  {
    {
      const int FirstKey = VK_LBUTTON; // 0x01
      const int LastKey = VK_OEM_CLEAR; // 0xFE

      // reset key state
      for (int Key = FirstKey; Key <= LastKey; Key++)
      {
        GetAsyncKeyState(Key);
      }

      TConsoleInputThread InputThread(FInput, Str, Result);

      InputThread.Start();

      double TimerD = double(Timer)/MSecsPerDay;
      double End = Now() + TimerD;
      while (!InputThread.IsFinished() &&
             ((Timer == 0) || (double(Now()) < End)))
      {
        ProcessMessages();
        InputThread.WaitFor(50);

        for (int Key = FirstKey; Key <= LastKey; Key++)
        {
          if ((GetAsyncKeyState(Key) & 0x01) != 0)
          {
            End = Now() + TimerD;
            // Finishing the loop nevertheless to reset state of all keys
          }
        }
      }
    }

    if (FPendingAbort || !Echo)
    {
      Print(L"\n");
    }

    if (FPendingAbort || (Str.Length() == 0))
    {
      Result = false;
      FPendingAbort = false;
    }
  }
  __finally
  {
    SetConsoleMode(FInput, PrevMode);
  }

  return Result;
}

bool __fastcall TOwnConsole::Input(UnicodeString & Str, bool Echo, unsigned int Timer)
{
  unsigned long PrevMode, NewMode;
  GetConsoleMode(FInput, &PrevMode);
  NewMode = PrevMode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
  if (Echo)
  {
    NewMode |= ENABLE_ECHO_INPUT;
  }
  else
  {
    NewMode &= ~ENABLE_ECHO_INPUT;
  }
  SetConsoleMode(FInput, NewMode);

  bool Result = false;

  try
  {
    {
      const int FirstKey = VK_LBUTTON;  
      const int LastKey = VK_OEM_CLEAR;  

       
      for (int Key = FirstKey; Key <= LastKey; Key++)
      {
        GetAsyncKeyState(Key);
      }

      TConsoleInputThread InputThread(FInput, Str, Result);

      InputThread.Start();

      double TimerD = double(Timer)/MSecsPerDay;
      double End = Now() + TimerD;
      while (!InputThread.IsFinished() &&
             ((Timer == 0) || (double(Now()) < End)))
      {
        ProcessMessages();
        InputThread.WaitFor(50);

        for (int Key = FirstKey; Key <= LastKey; Key++)
        {
          if ((GetAsyncKeyState(Key) & 0x01) != 0)
          {
            End = Now() + TimerD;
             
          }
        }
      }
    }

    if (FPendingAbort || !Echo)
    {
      Print(L"\n");
    }

    if (FPendingAbort || (Str.Length() == 0))
    {
      Result = false;
      FPendingAbort = false;
    }
  }
  __finally
  {
    SetConsoleMode(FInput, PrevMode);
  }

  return Result;
}
