[英]WPF: application Idle Time
I need to count the idle time of my WPF application (Idle time = when no keyboard input,mouse input (movement + clicks ) had occurred ). 我需要计算我的WPF应用程序的空闲时间(空闲时间=没有键盘输入,鼠标输入(移动+点击))。 So far I tried 2 approaches but none of them seem to be working:
到目前为止,我尝试了两种方法,但似乎没有一种方法可行:
Any Other ideas? 还有其他想法吗? or maybe a way to modify the 2nd solution to work?
或者可能是修改第二个解决方案的方法?
I solved the problem using a few different techniques rolled up to give me a pretty good solution. 我用一些不同的技术解决了这个问题,为我提供了一个很好的解决方案。 I use GetLastInput to work out when the system was last touched This is well documented elsewhere, but here's my method:
我使用GetLastInput来解决系统上次触摸的问题这在其他地方有详细记载,但这是我的方法:
public static class User32Interop
{
public static TimeSpan GetLastInput()
{
var plii = new LASTINPUTINFO();
plii.cbSize = (uint)Marshal.SizeOf(plii);
if (GetLastInputInfo(ref plii))
return TimeSpan.FromMilliseconds(Environment.TickCount - plii.dwTime);
else
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
struct LASTINPUTINFO {
public uint cbSize;
public uint dwTime;
}
}
This only tells me when the system has been idle, not the application. 这只告诉我系统何时处于空闲状态,而不是应用程序。 If the user clicks into Word and works there for an hour, I still want a timeout.
如果用户点击Word并在那里工作了一个小时,我仍然想要超时。 To handle this case, I simply remember when my application loses focus by overriding the OnDeactivated and OnActivated methods on the application object:
为了处理这种情况,我只记得当我的应用程序通过覆盖应用程序对象上的OnDeactivated和OnActivated方法而失去焦点时:
override protected void OnDeactivated(EventArgs e)
{
this._lostFocusTime = DateTime.Now;
base.OnDeactivated(e);
}
protected override void OnActivated(EventArgs e)
{
this._lostFocusTime = null;
base.OnActivated(e);
}
My IsIdle routine was added to the application object. 我的IsIdle例程已添加到应用程序对象中。 It handles the global case where the app has focus but nothing happened (IsMachineIdle) and the specific case where the application lost focus while the user is doing other stuff (isAppIdle ):
它处理应用程序具有焦点但未发生任何事情的全局情况(IsMachineIdle)以及应用程序在用户执行其他操作时失去焦点的特定情况(isAppIdle):
public bool IsIdle
{
get
{
TimeSpan activityThreshold = TimeSpan.FromMinutes(1);
TimeSpan machineIdle = Support.User32Interop.GetLastInput();
TimeSpan? appIdle = this._lostFocusTime == null ? null : (TimeSpan?)DateTime.Now.Subtract(_lostFocusTime.Value);
bool isMachineIdle = machineIdle > activityThreshold ;
bool isAppIdle = appIdle != null && appIdle > activityThreshold ;
return isMachineIdle || isAppIdle;
}
}
The last thing I did was create a timer loop that polled this flag event few seconds. 我做的最后一件事是创建一个定时器循环,在几秒钟内轮询这个标志事件。
This seems to work fine. 这似乎工作正常。
Well no one seemed to answer so I continued digging and found a relatively simple solution using the OS last input + up time. 好吧没有人回答所以我继续挖掘并找到一个相对简单的解决方案,使用操作系统最后输入+运行时间。 the code is really simple but this solution make me do data polling which I never recommend and also instead of being in the application level it's in the OS level which is not the exact solution I needed.
代码非常简单但是这个解决方案让我进行数据轮询,这是我从不推荐的,而且不是在应用程序级别,而是在操作系统级别,这不是我需要的确切解决方案。 If someone ever opens this thread this is the code, just use GetIdleTime():
如果有人打开这个线程这是代码,只需使用GetIdleTime():
public class IdleTimeService
{
//Importing the Dll & declaring the necessary function
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
/// <summary>
/// return the current idle time (in ms)
/// </summary>
/// <returns>current idle time in ms</returns>
public static int GetIdleTime()
{
//Creating the object of the structure
LASTINPUTINFO lastone = new LASTINPUTINFO();
//Initialising
lastone.cbSize = (uint)Marshal.SizeOf(lastone);
lastone.dwTime = 0;
int idleTime = 0;
//To get the total time after starting the system.
int tickCount = System.Environment.TickCount;
//Calling the dll function and getting the last input time.
if (GetLastInputInfo(ref lastone))
{
idleTime = tickCount - (int)lastone.dwTime;
return idleTime;
}
else
return 0;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.