Jump to content
ChrisChuah

auto close or logout when no mouse activity

Recommended Posts

Hi

Is there a way to auto detect when there is no mouse activity and the VCL application will log out for users?

 

thanks

chris

Share this post


Link to post

Take a look at the CloseApplication.pas unit in an old library of mine

 

From the README in the main folder of the repository:

Quote

This component includes routines written by someone named Neil on the DBISAM newsgroups several years ago. Turned into a component, this attaches to some keyboard and mouse Windows hooks to watch for inactivity on the computer and pops up a message with a count-down timer to close the application. One use case is a 2-tier database applications that leave files and records open.

 

  • Like 1

Share this post


Link to post
15 hours ago, ChrisChuah said:

Is there a way to auto detect when there is no mouse activity and the VCL application will log out for users?

One way is to run a timer that polls GetLastInputInfo() to see if the reported dwTime changes.  If it doesn't change for awhile, log out.

 

However, that is a global setting for the entire OS, and it includes keyboard input, not just mouse input.  If you just want to monitor mouse activity inside your own app, another option would be to use the TApplication(Events).OnMessage event to look for WM_MOUSE... messages, resetting a timer whenever a mouse event is detected, and log out if the timer elapses.

Edited by Remy Lebeau

Share this post


Link to post
8 minutes ago, Remy Lebeau said:

One way is to run a timer that polls GetLastInputInfo() to see if the reported dwTime changes.

Are you able to run this reliably in a recent Windows? My attempts showed that it always just returns false.

Share this post


Link to post
2 minutes ago, Uwe Raabe said:

Are you able to run this reliably in a recent Windows? My attempts showed that it always just returns false.

We also use GetLastInputInfo() for exactly that (revoking any special permissions on a kiosk system if there has been no input for a few minutes). It's been working fine since we added it in 2016.

 

Keep in mind that the tick count returned by GetLastInputInfo() is just a DWORD - Meaning it will roll over after 49.7 days. Our users were not happy when they were immediately logged out again after the system had been running for more than 50 days 😐

Edited by Der schöne Günther

Share this post


Link to post
1 hour ago, Uwe Raabe said:

Are you able to run this reliably in a recent Windows? My attempts showed that it always just returns false.

I haven't tried it recently, no.  But I have used it in the past without problem.

Share this post


Link to post
1 hour ago, Der schöne Günther said:

Keep in mind that the tick count returned by GetLastInputInfo() is just a DWORD - Meaning it will roll over after 49.7 days. Our users were not happy when they were immediately logged out again after the system had been running for more than 50 days 😐

That would happen only if you are interpreting the actual value of the DWORD.  I would just use my own timestamp (that doesn't roll over) to keep track of when the DWORD changes value between successive calls to GetLastInputInfo(), regardless of its actual value, Even if the DWORD rolls over, it is still a change in value.  Even the documentation says that the DWORD is "not guaranteed to be incremental".

Edited by Remy Lebeau

Share this post


Link to post

Hi

I managed to implement it in windows using this event

TfrmMain : TForm

        Gauge1 : TGauge;

        tmrInactivity: TTimer;
        procedure FormCreate(Sender: TObject);
        procedure tmrInactivityTimer(Sender: TObject);
private    

        FInactivityTimeout : cardinal;
        FInactivityCounter : cardinal;

 

        // cc : application event to handle key down and left mouse click
        // cc : for activity timeout
        procedure ApplicationEventMsg(var Msg: tagMSG; var Handled: Boolean);
public

 

end;

 

procedure TfrmMain.FormCreate(Sender: TObject);

var

  l_ini : TIniFile;

begin

    // this event msg is to capture keyboard and mouse event

    Application.OnMessage := ApplicationEventMsg;

 

    // cc : get the amount of seconds allowed before timeout

     l_ini := TIniFile.create(ChangeFileExt(Application.ExeName, '.ini'));

    FInactivityTimeout := l_ini.ReadInteger('Main', 'Inactivity Timeout', 60);
    Gauge1.MaxValue := FInactivityTimeout;
    Gauge1.MinValue := 0;
    FInactivityCounter := 0;

   l_ini.Free;

end;
 

procedure TfrmMain.tmrInactivityTimer(Sender: TObject);
begin
  // Inactivity timeout will disconnect every connection
  tmrInactivity.Enabled := false;
  if (not DataModule1.getLoginSuccess) then begin
    FInactivityCounter := 0;
    Gauge1.Progress := 0;
    tmrInactivity.Enabled := true;
    exit;
  end;
  if (FInactivityCounter > FInactivityTimeout) then begin
      DataModule1.closeAll;
    end;
    FInactivityCounter := 0;
    Gauge1.Progress := 0;
  end
  else begin
    FInactivityCounter := FInActivityCounter +1;
    Gauge1.Progress := FInactivityCounter;
  end;
  tmrInactivity.Enabled := true;
end;
 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×