Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当用户空闲或不活动时,如何在Windows应用程序中设置计时器_C#_.net_Winforms_Timer - Fatal编程技术网

C# 当用户空闲或不活动时,如何在Windows应用程序中设置计时器

C# 当用户空闲或不活动时,如何在Windows应用程序中设置计时器,c#,.net,winforms,timer,C#,.net,Winforms,Timer,在Windows窗体中,我有一个关于在用户空闲或不活动时设置计时器的问题。我需要定时器设置任何鼠标事件。如果用户做出任何时刻,那么我需要重置计时器。这就是要求。代码在这里 using System; using System.Windows.Forms; using Timer = System.Windows.Forms.Timer; namespace FormsTimerSetup.Globals { public class SetApplicationTimeOut : Fo

在Windows窗体中,我有一个关于在用户空闲或不活动时设置计时器的问题。我需要定时器设置任何鼠标事件。如果用户做出任何时刻,那么我需要重置计时器。这就是要求。代码在这里

using System;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;

namespace FormsTimerSetup.Globals
{
    public class SetApplicationTimeOut : Form
    {
        #region
        /// <summary>
        /// Private Timer Property
        /// </summary>
        private static Timer _timer;

        /// <summary>
        /// Timer Property
        /// </summary>
        public static Timer Timer
        {
            get
            {
                return _timer;
            }
            set
            {
                if (_timer != null)
                {
                    _timer.Tick -= Timer_Tick;
                }

                _timer = value;

                if (_timer != null)
                {
                    _timer.Tick += Timer_Tick;
                }
            }
        }
        #endregion

        #region Events
        public event EventHandler UserActivity;
        #endregion

        #region Constructor
        /// <summary>
        /// Default/Parameterless SetApplicationTimeOut Constructor
        /// </summary>
        public SetApplicationTimeOut()
        {
            KeyPreview = true;

            FormClosed += ObservedForm_FormClosed;
            MouseMove += ObservedForm_MouseMove;
            KeyDown += ObservedForm_KeyDown;
        }
        #endregion

        #region Inherited Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnUserActivity(EventArgs e)
        {
            // Invoking the UserActivity delegate
            UserActivity?.Invoke(this, e);
        }

        /// <summary>
        /// 
        /// </summary>
        public void SetTimeOut()
        {
            // postpone auto-logout by 30 minutes
            _timer = new Timer
            {
                Interval = (30 * 60 * 1000) // Timer set for 30 minutes
            };

            Application.Idle += Application_Idle;

            _timer.Tick += new EventHandler(Timer_Tick);
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ObservedForm_MouseMove(object sender, MouseEventArgs e)
        {
            OnUserActivity(e);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ObservedForm_KeyDown(object sender, KeyEventArgs e)
        {
            OnUserActivity(e);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ObservedForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            FormClosed -= ObservedForm_FormClosed;
            MouseMove -= ObservedForm_MouseMove;
            KeyDown -= ObservedForm_KeyDown;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Application_Idle(object sender, EventArgs e)
        {
            _timer.Stop();
            _timer.Start();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Timer_Tick(object sender, EventArgs e)
        {
            _timer.Stop();
            Application.Idle -= Application_Idle;
            MessageBox.Show("Application Terminating");
            Application.Exit();
        }
        #endregion
    }
}
使用系统;
使用System.Windows.Forms;
使用Timer=System.Windows.Forms.Timer;
命名空间FormsTimerSetup.Globals
{
公共类SetApplicationTimeOut:表单
{
#区域
/// 
///专用计时器属性
/// 
专用静态定时器_定时器;
/// 
///计时器属性
/// 
公共静态定时器
{
得到
{
返回定时器;
}
设置
{
如果(_timer!=null)
{
_timer.Tick-=定时器_Tick;
}
_定时器=值;
如果(_timer!=null)
{
_timer.Tick+=定时器_Tick;
}
}
}
#端区
#地区活动
公共事件事件处理程序用户活动;
#端区
#区域构造函数
/// 
///默认/无参数SetApplicationTimeOut构造函数
/// 
public SetApplicationTimeOut()
{
KeyPreview=true;
FormClosed+=观察到的Form_FormClosed;
MouseMove+=观察到的形式\u MouseMove;
KeyDown+=观察到的形式u KeyDown;
}
#端区
#区域继承方法
/// 
/// 
/// 
/// 
受保护的虚拟void OnUserActivity(EventArgs e)
{
//调用UserActivity委托
UserActivity?调用(this,e);
}
/// 
/// 
/// 
公共void SetTimeOut()
{
//将自动注销延迟30分钟
_定时器=新定时器
{
间隔=(30*60*1000)//计时器设置为30分钟
};
Application.Idle+=应用程序\u Idle;
_timer.Tick+=新事件处理程序(timer\u Tick);
}
#端区
#区域私有方法
/// 
/// 
/// 
/// 
/// 
private void observed form_MouseMove(对象发送方,MouseEventArgs e)
{
主动性(e);
}
/// 
/// 
/// 
/// 
/// 
私有void ObservedForm_KeyDown(对象发送方,KeyEventArgs e)
{
主动性(e);
}
/// 
/// 
/// 
/// 
/// 
私有void ObservedForm_FormClosed(对象发送方,FormClosedEventArgs e)
{
FormClosed-=观察到的Form_FormClosed;
MouseMove-=观察到的形式\u MouseMove;
KeyDown-=观察到的形式u KeyDown;
}
/// 
/// 
/// 
/// 
/// 
私有静态无效应用程序\u空闲(对象发送方、事件参数)
{
_timer.Stop();
_timer.Start();
}
/// 
/// 
/// 
/// 
/// 
私有静态无效计时器(对象发送器、事件参数)
{
_timer.Stop();
Application.Idle-=应用程序\u Idle;
MessageBox.Show(“应用程序终止”);
Application.Exit();
}
#端区
}
}
我已经实现了代码,但不确定它是否是正确的方法


任何潜在客户都将不胜感激。

我不会深入了解您的代码,但我想直接解决这个问题。 我认为在这种情况下,“环岛”会起作用

例如,您可以在鼠标移动时进行检查,并将其与初始位置进行比较

在上面添加初始化组件()

然后添加以下内容:

  void gmh_TheMouseMoved()
  {
     if(XY==false)
     {
        MouseX = Convert.ToInt32(Cursor.Position.X);
        MouseY = Convert.ToInt32(Cursor.Position.Y);
     }
    else
    {
        MouseX1 = Convert.ToInt32(Cursor.Position.X);
        MouseY1 = Convert.ToInt32(Cursor.Position.Y);
        XY = true;
        if(MouseX1==MouseX && MouseY1==MouseY)
        {
            if(yourTimerNameHere.Enabled==false)
            {
                yourTimerNameHere.Start();
            }                
        }
        else
        {
            yourTimerNameHere.Stop();
            yourTimerNameHere.Start();
        }
    }

  }
将其添加到表单的类之外:

public delegate void MouseMovedEvent();

public class GlobalMouseHandler : IMessageFilter
{
   private const int WM_MOUSEMOVE = 0x0200;

  public event MouseMovedEvent TheMouseMoved;

  public bool PreFilterMessage(ref Message m)
  {
     if (m.Msg == WM_MOUSEMOVE)
     {
        if (TheMouseMoved != null)
        {
           TheMouseMoved();
        }
     }
     return false;
  }
}

接下来创建4个int,分别命名为MouseX=0、MouseY=0、MouseX1=0和MouseY1=0以及bool XY=false

所以实际上,每当光标移动时,位置就会被记录下来,并与下一个位置进行比较。因此,您可以检查鼠标是否空闲

请注意,我还没有测试这段代码,所以请随时回复任何错误

问:“我需要定时器设置任何鼠标事件…如果用户进行任何移动,那么我需要重置定时器…任何线索将不胜感激。”

我会尽量提供一些线索,希望对你有用。您说希望MouseMove事件重置计时器,但有一个问题:每当子控件有焦点时,都是子控件接收鼠标事件,而主窗体没有。这是可以解决的

简短的回答是:“在主窗口类上实现IMessageFilter接口,以便在检测到鼠标移动时重置计时器。”添加MessageFilter可以在鼠标消息发送到焦点控件之前拦截鼠标消息

因此,现在我必须向您提供所有详细信息,下面是一个很长的答案:它首先向我们的主表单1添加IMessageFilter接口,如下所示:

public partial class Form1 : Form, IMessageFilter
IMessageFilter要求我们的类只实现一个方法:

    public bool PreFilterMessage(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_MOUSEMOVE:
            // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
            // Commit f9367d7c added at OP's request
            case WM_KEYDOWN:  
            // This makes WakeUp persist if user is typing in the textbox.
            // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                TimeOutState = TimeOutState.WakeUp;
                break;
        }
        return false; // Do not suppress downstream message
    }
    const int  // WinOS Messages
        WM_KEYDOWN = 0x0100,
        WM_MOUSEMOVE = 0x0200;
您可以看到,现在任何鼠标移动都会将我们的应用程序的TimeOutState设置回“唤醒”

enum TimeOutState{ WakeUp, Sleeping, Warning, Exit }
我们只需要一个计时器,计时器的每一个滴答声间隔(这里设置为5秒)将减少一个状态。如果鼠标不移动,它会一直递减,最后退出

下面是运行应用程序60秒的60秒。您可以看到每5秒或鼠标移动时发生的更改。如果您想运行该示例,可以从我们的GitHub repo获得最新提交

以下是其余的详细信息:

  • 需要连接MessageFilter。因为我们需要窗体有它的窗口句柄,所以我们
    enum TimeOutState{ WakeUp, Sleeping, Warning, Exit }
    
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        // When our main window is ready for messages, add the MessageFilter
        Application.AddMessageFilter(this);
        // ...and start the timer for the first time.
        TimeOutState = TimeOutState.WakeUp;
    }
    
    public Form1()
    {
        InitializeComponent();
        _wdt = new Timer();            
        _wdt.Interval = 5000; // Use a very short time-out for this demo
        _wdt.Tick += _wdt_Tick;
    }
    Timer _wdt; // Watch-Dog Timer
    
    private void _wdt_Tick(object sender, System.EventArgs e)
    {
        // A tick reduces the TimeOutState by 1
        TimeOutState = (TimeOutState)(TimeOutState - 1);
    }
    
    TimeOutState TimeOutState
    {
        get => _timeOutState;
        set
        {
            switch (value)
            {
                case TimeOutState.WakeUp:
                    _wdt.Stop();
                    _wdt.Start();
                    break;
                case TimeOutState.Exit:
                    _wdt.Stop();
                    Application.Exit();
                    return;
            }
            if (value != _timeOutState)  // If state changes, write message
            {
                Debug.WriteLine(value.ToString(), _timeOutState.ToString());
                // In a timer callback that changes the UI, it's
                // best to post the action in the message queue.
                BeginInvoke((MethodInvoker)delegate
                {
                    textBox1.AppendText(_timeOutState.ToString());
                    if (TimeOutState == TimeOutState.Warning)
                    {
                        textBox1.AppendText(
                            ": Closing in " + (_wdt.Interval / 1000).ToString() + " seconds.");
                    }
                    textBox1.AppendText(Environment.NewLine);
                    textBox1.Select(textBox1.TextLength, 0);
                });
            }
            _timeOutState = value;
        }
    }
    TimeOutState _timeOutState = (TimeOutState)(-1);    // Initialize to invalid state