using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Threading; namespace JinYuan.ControlLib { /// /// 监视鼠标键盘操作。 /// public class UserStateMonitor : Component { //通过 Interval 属性调节扫描键盘鼠标状态的间隔时间,通过 Timeout 属性(无键盘操作时间间隔)控制判断是否离开 /// /// 离开时间,单位:秒 /// private int _timeout = 5000; private int _lastActiveTick; private Timer _timer; private int _interval = 1000; private bool _started; private bool _active = true; private static readonly object EventUseStateChanged = new object(); public UserStateMonitor() : base() { } public UserStateMonitor(IContainer container) : base() { container.Add(this); } public event UserStateChangedEventHandler UserStateChanged { add { base.Events.AddHandler(EventUseStateChanged, value); } remove { base.Events.RemoveHandler(EventUseStateChanged, value); } } /// /// 默认值:30分钟 /// [DefaultValue(1800000)] public int Timeout { get { return _timeout; } set { _timeout = Math.Max(5000, value); } } [DefaultValue(1000)] public int Interval { get { return _interval; } set { _interval = Math.Max(500, value); if (_started) { Timer.Change(0, _interval); } else { Timer.Change(System.Threading.Timeout.Infinite, _interval); } } } private Timer Timer { get { if (_timer == null) { _timer = new Timer( new TimerCallback(delegate (object obj) { LASTINPUTINFO lii = new LASTINPUTINFO(); lii.size = 8; if (GetLastInputInfo(ref lii)) { _lastActiveTick = Math.Max(lii.lastTick, _lastActiveTick); bool active = Environment.TickCount - _lastActiveTick < _timeout; if (_active != active) { _active = active; OnUserStateChanged(new UserStateChangedEventArgs(active)); } } }), null, System.Threading.Timeout.Infinite, _interval); } return _timer; } } public void Start() { if (!_started) { Timer.Change(_interval, _interval); _started = true; } } /// /// 开始监控 /// /// 监控时间间隔,单位:分钟 public void Start(int timeOut) { if (!_started) { _timeout = timeOut * 1000;//转换成秒 Timer.Change(_interval, _interval); _started = true; } } public void Stop() { if (_started) { Timer.Change(System.Threading.Timeout.Infinite, _interval); _started = false; } } [StructLayout(LayoutKind.Sequential)] private struct LASTINPUTINFO { public int size; public int lastTick; } [DllImport("user32.dll")] private static extern bool GetLastInputInfo(ref LASTINPUTINFO lii); protected virtual void OnUserStateChanged(UserStateChangedEventArgs e) { UserStateChangedEventHandler handler = base.Events[EventUseStateChanged] as UserStateChangedEventHandler; if (handler != null) { handler(this, e); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { Stop(); if (_timer != null) { _timer.Dispose(); _timer = null; } } } } }