windows 如何检测不活跃用户

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2212823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:06:33  来源:igfitidea点击:

How to detect inactive user

windowsdelphiuser-inactivity

提问by Harriv

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 of time.

如何在 Windows 应用程序中检测非活动(空闲)用户?我想在一段时间内没有来自用户的任何输入(键盘、鼠标)时关闭应用程序。

回答by James Campbell

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.

要跟踪用户的空闲时间,您可以挂钩键盘和鼠标活动。但是请注意,安装系统范围的消息挂钩是一件非常具有侵入性的事情,应该尽可能避免,因为它需要将挂钩 DLL 加载到所有进程中。

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

另一种解决方案是使用GetLastInputInfoAPI 函数(如果您的应用程序在 Win2000(及更高版本)机器上运行)。 GetLastInputInfo检索最后一个输入事件的时间(以毫秒为单位)(当接收到最后一个检测到的用户活动时,无论是来自键盘还是鼠标)。

Here's a simple example. The SecondsIdlefunction returns a number of second with no user activity (called in an OnTimerevent of a TTimercomponent).

这是一个简单的例子。该SecondsIdle函数返回没有用户活动的秒数(在组件的OnTimer事件中调用TTimer)。

~~~~~~~~~~~~~~~~~~~~~~~~~
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

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

回答by John Knoeller

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

当屏幕保护程序即将启动时,您的应用程序将收到一条WM_SYSCOMMAND带有SC_SCREENSAVE命令 id的消息。会这样吗?SC_MONITORPOWER当监视器即将变为空白时,还有命令 ID(也是 WM_SYSCOMMAND 消息)。

Edit: looking at the comments, it appears that you don't care about whether the useris inative, but rather whether your applicationis 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 pumphook into the message loop that TApplication implements. Or GetLastInputInfo

您还可以注意泵中的消息,以注意您的应用程序是否有任何用户输入消息,在 C++ 中向泵添加代码是微不足道的,在 delphi 中,您可以使用 WH_GETMESSAGE 钩子来监视泵钩子到消息中TApplication 实现的循环。或 GetLastInputInfo

回答by Please_Dont_Bully_Me_SO_Lords

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.

这个 SecondsIdle 根本不起作用。方法是将 TTimer 与第二个变量结合使用,该变量在用户每次输入鼠标或键盘时重置。