How to detect inactive user

后端 未结 4 595
醉梦人生
醉梦人生 2020-12-12 18:09

How to detect inactive (idle) user in Windows application? I\'d like to shutdown application when there hasn\'t been any input (keyboard, mouse) from user for certain period

相关标签:
4条回答
  • 2020-12-12 18:43

    You might want to see the answer to this question: How to tell when Windows is inactive [1] it is basically same question the solution suggested is to use the GetLastInputInfo [2] API call.

    This post explains some aspects as well: (The Code Project) How to check for user inactivity with and without platform invokes in C# [3]

    [1] How to tell when Windows is inactive
    [2] http://msdn.microsoft.com/en-us/library/ms646302%28VS.85%29.aspx
    [3] http://www.codeproject.com/KB/cs/uim.aspx

    0 讨论(0)
  • 2020-12-12 18:50

    This SecondsIdle doens't work at all. The way is to use a TTimer combined with a second variable that resets every time user inputs mouse or keyboard.

    0 讨论(0)
  • 2020-12-12 18:52

    To track a user's idle time you could hook keyboard and mouse activity. Note, however, that installing a system-wide message hook is a very invasive thing to do and should be avoided if possible, since it will require your hook DLL to be loaded into all processes.

    Another solution is to use the GetLastInputInfo API function (if your application is running on Win2000 (and up) machines). GetLastInputInfo retrieves the time (in milliseconds) of the last input event (when the last detected user activity has been received, be it from keyboard or mouse).

    Here's a simple example. The SecondsIdle function returns a number of second with no user activity (called in an OnTimer event of a TTimer component).

    ~~~~~~~~~~~~~~~~~~~~~~~~~
    function SecondsIdle: DWord;
    var
       liInfo: TLastInputInfo;
    begin
       liInfo.cbSize := SizeOf(TLastInputInfo) ;
       GetLastInputInfo(liInfo) ;
       Result := (GetTickCount - liInfo.dwTime) DIV 1000;
    end;
    
    procedure TForm1.Timer1Timer(Sender: TObject) ;
    begin
       Caption := Format('System IDLE last %d seconds', [SecondsIdle]) ;
    end;
    

    http://delphi.about.com/od/adptips2004/a/bltip1104_4.htm

    0 讨论(0)
  • 2020-12-12 18:56

    Your application will get a WM_SYSCOMMAND message with SC_SCREENSAVE as a command id when the Screen Saver is about to kick in. Would that do? there's also the SC_MONITORPOWER command id when the monitor is about to blank (also a WM_SYSCOMMAND message).

    Edit: looking at the comments, it appears that you don't care about whether the user is inative, but rather whether your application is inactive.

    This is easy. If your app is minimized, then the user isn't interacting with it. If your app is not the foreground application, that's a good inicator as well.

    You could also pay attention to messages in your pump to notice if there have been any user input messages to your app, In C++ adding code to the pump is trivial, in delphi you can use a WH_GETMESSAGE hook to monitor the pump hook into the message loop that TApplication implements. Or GetLastInputInfo

    0 讨论(0)
提交回复
热议问题