2006. április 4., kedd

Implement an inactivity timer with automatic logout


Problem/Question/Abstract:

Anyone have suggestions on how to implement an inactivity timer? My application has passwords for various functions, and I need to be able to automatically logout a user if they've been inactive for 10 minutes, etc.. I suppose I'd tie into the messaging queue, looking at keyboard and mouse events. The implementation should cover activity related to any form in my application, but not any activity outside the application.

Answer:

In your main form, add the integer variables "ShutdownCounter" and "ShutDownDelay". Add a TApplicationEvents and a TTimer control. Set the timer interval to, say, 5000 mSecs. In the form's OnCreate event handler, add:

{ ... }
    {Set up the automatic log off routine. Get the users auto logoff time,
                which defaults to 20 minutes. 0 is never autologoff}
shutDownDelay := UserIni.ReadInteger('Settings', 'Auto Shutdown Delay', 20);
shutDownDelay := shutDownDelay * 60;
ShutdownCounter := 0;
if shutDownDelay > 0 then
  timShutDown.Enabled := true;
    {Enable the timer if you want to use a timeout for this user}

This format allows you to add different logoff times for different users, or completely disable autologoff - I do this on my development system.

In the TApplicationEvents OnMessage event handler, add code to check for keypresses, or left mouse button clicks (or any other message you want to use to keep the app running). Whenever any of these messages are received by the application, reset the ShutDownCounter to zero.

procedure TfrmAutoProMain.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  case Msg.message of
    WM_KEYDOWN, WM_LBUTTONDOWN:
      ShutdownCounter := 0;
  end;
end;

In the TTimer OnTimer event handler, add code to compare the current value of ShutDownCounter against the ShutDownDelay for this user. If the counter is larger than the delay, then we need to exit the application. In my apps, I actually show another window with a 30 second decrementing progress bar which gives the user notification that the app is about to shutdown, and gives him a chance to keep the app alive - that's the references to dlgAutoLogOff .

procedure TfrmAutoProMain.timShutDownTimer(Sender: TObject);
begin
  Inc(ShutdownCounter, 5);
    {Increase counter by 5 seconds (if TTimer interval was 5000)}
  if ShutdownCounter >= shutDownDelay then
  begin
    timShutDown.Enabled := false;
    {The next block handles a "last chance" warning dialog to allow the user
                to stay alive}
    dlgAutoLogOff := TdlgAutoLogOff.Create(self);
    try
      dlgAutoLogOff.Show;
      repeat
        Application.ProcessMessages;
      until
        (dlgAutoLogOff.ModalResult = mrOK) or (dlgAutoLogOff.ModalResult = mrAbort);
      if dlgAutoLogOff.ModalResult = mrOK then
      begin
        ShutdownCounter := 0;
        timShutDown.Enabled := true;
      end
      else
        Application.Terminate;
    finally
      dlgAutoLogOff.Free;
    end;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése