开发者

How to detect inactive user

How to detect inactive (idle) user in Windows application? I'd like to shutdown application when there hasn't been any in开发者_运维百科put (keyboard, mouse) from user for certain period of time.


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


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


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜