我们使用GetLastInputInfo并从GetTickCount64的结果中计算出差异以确定空闲状态。但是,GetLastInputInfo返回的滴答计数被写入LASTINPUTINFO的成员dwTime中,该成员是DWORD,因此是无符号的32位整数,最大值为,最大值为4294967295,相当于〜49天。在正常运行时间更长的机器上,这当然会导致函数报告错误的值。
显然没有叫GetLastInputInfo64的函数,但是也许函数的名称不同?
答案 0 :(得分:0)
我们使用一种解决方法。
仅使用GetLastInputInfo()
的结果来检测dwTick
是否已更改,而无需关心更改了多少。
定期执行此操作。
滴答声改变后(该值与上一个读数不同),启动您自己的计时器,并使用该计时器检测输入何时变为空闲状态(例如30秒)。
您永远不需要使用这种方法来处理环绕式广告。
答案 1 :(得分:0)
@Anders:?
public class IdleDetection
{
private struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
private readonly Timer _idleTimer;
private double _idleSeconds = 0;
private uint _previousLastInput = 0;
private DateTime _idleStart = DateTime.Now;
private object _lock = new object();
public IdleDetection()
{
_idleTimer = new Timer(TimerCallback, null, 1000, Timeout.Infinite);
}
public TimeSpan IdleTime
{
get {
lock (_lock)
{
return TimeSpan.FromSeconds(_idleSeconds);
}
}
}
private void TimerCallback(object state)
{
lock (_lock)
{
var lastInput = GetLastInputInfoValue();
if (lastInput == _previousLastInput)
{
_idleSeconds = (DateTime.Now - _idleStart).TotalSeconds;
}
else
{
_idleSeconds = 0;
_idleStart = DateTime.Now;
}
_previousLastInput = lastInput;
}
_idleTimer.Change(1000, Timeout.Infinite);
}
private static uint GetLastInputInfoValue()
{
LASTINPUTINFO lastInPut = new LASTINPUTINFO();
lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);
GetLastInputInfo(ref lastInPut);
return lastInPut.dwTime;
}
}