Search code examples
delphievent-handlingmouseeventkeystrokeidle-timer

Get idle time of windows and/or application (time since last mouse move or key stroke)


I want to perform background tasks (Updates, Backups, Calculations, ...) at a time when nobody is using my application.

Therefore, I want to determine the time since the last keystroke and/or mouse move in my application. If there is no user activity for more than a specific time, the chance is high not to disturb a user. Multithreading is not an option for me.

I want to avoid touching every single OnMouseDown-/OnKeyPress-Event of every component in my application because this doesn't make any sense.

How can I get

a) The time since last input in Windows

b) The time since last input in my application


Solution

  • This solution works for problem
    a) The time since last input in Windows
    Every mouse move or keyboard input resets the time to zero.

    function GetTimeSinceLastUserInputInWindows(): TTimeSpan;
    var
       lastInput: TLastInputInfo;
       currentTickCount: DWORD;
       millisecondsPassed: Double;
    begin
      lastInput := Default(TLastInputInfo);
      lastInput.cbSize := SizeOf(TLastInputInfo);
    
      Win32Check( GetLastInputInfo(lastInput) );
      currentTickCount := GetTickCount();
    
      if (lastInput.dwTime > currentTickCount) then begin // lastInput was before 49.7 days but by now, 49.7 days have passed
        millisecondsPassed :=
          (DWORD.MaxValue - lastInput.dwTime)
          + (currentTickCount * 1.0); // cast to float by multiplying to avoid DWORD overflow
        Result := TTimeSpan.FromMilliseconds(millisecondsPassed);
      end else begin
        Result := TTimeSpan.FromMilliseconds(currentTickCount - lastInput.dwTime );
      end;
    end;
    

    https://www.delphipraxis.net/1504414-post3.html