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.
精彩评论