Hide mouse cursor after an idle time

前端 未结 3 1665
南笙
南笙 2020-12-02 19:25

I want to hide my mouse cursor after an idle time and it will be showed up when I move the mouse. I tried to use a timer but it didn\'t work well. Can anybody help me? Pleas

相关标签:
3条回答
  • 2020-12-02 19:54

    Need to account for Environment.Tickcount being negative:

    public static class User32Interop
    {
    
        public static TimeSpan GetLastInput()
        {
            var plii = new LASTINPUTINFO();
            plii.cbSize = (uint)Marshal.SizeOf(plii);
    
            if (GetLastInputInfo(ref plii))
            {
                int idleTime = unchecked(Environment.TickCount - (int)plii.dwTime);
                return TimeSpan.FromMilliseconds(idleTime);
            }
            else
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
    
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
    
        struct LASTINPUTINFO
        {
            public uint cbSize;
            public uint dwTime;
        }
    }
    
    0 讨论(0)
  • 2020-12-02 19:59

    If you are using WinForms and will only deploy on Windows machines then it's quite easy to use user32 GetLastInputInfo to handle both mouse and keyboard idling.

    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 Win32Exception(Marshal.GetLastWin32Error());
      }
    
      [DllImport("user32.dll", SetLastError = true)]
      static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
    
      struct LASTINPUTINFO
      {
        public uint cbSize;
        public uint dwTime;
      }
    }
    

    And then in your Form

    public partial class MyForm : Form
    {
      Timer activityTimer = new Timer();
      TimeSpan activityThreshold = TimeSpan.FromMinutes(2);
      bool cursorHidden = false;
    
      public Form1()
      {
        InitializeComponent();
    
        activityTimer.Tick += activityWorker_Tick;
        activityTimer.Interval = 100;
        activityTimer.Enabled = true;
      }
    
      void activityWorker_Tick(object sender, EventArgs e)
      {
        bool shouldHide = User32Interop.GetLastInput() > activityThreshold;
        if (cursorHidden != shouldHide)
        {
          if (shouldHide)
            Cursor.Hide();
          else
            Cursor.Show();
    
          cursorHidden = shouldHide;
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-02 20:06

    Here is a contrived example of how to do it. You probably had some missing logic that was overriding the cursor's visibility:

    public partial class Form1 : Form
    {
        public TimeSpan TimeoutToHide { get; private set; }
        public DateTime LastMouseMove { get; private set; }
        public bool IsHidden { get; private set; }
    
        public Form1()
        {
            InitializeComponent();
            TimeoutToHide = TimeSpan.FromSeconds(5);
            this.MouseMove += new MouseEventHandler(Form1_MouseMove);
        }
    
        void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            LastMouseMove = DateTime.Now;
    
            if (IsHidden) 
            { 
                Cursor.Show(); 
                IsHidden = false; 
            }
        }
    
        private void timer1_Tick(object sender, EventArgs e)
        {
            TimeSpan elaped = DateTime.Now - LastMouseMove;
            if (elaped >= TimeoutToHide && !IsHidden)
            {
                Cursor.Hide();
                IsHidden = true;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题