记录|如何全局监听鼠标和键盘等事件

目录


前言

参考文章:
C# winfrom 长时间检查不到操作,自动关闭应用程序

本来是想,如果一段时间没有操作软件,这个软件就自动退出的任务。但是在C#中,采用winform后,有很大的困难。表现为:

  • 监听困难,理论上是只要进行Form监听就可以了,但是实际上Form上面有许多的Panel和Button等控件在上面进行监听,所以如果要写鼠标、按钮等监听事件,会导致要N多个控件的重复性写法。
  • 一查找这种全局监听的,很多CSDN中都采用HOOK钩子的写法。而这种写法一则我没用过,二则会和系统抢资源,属于影响性能的一种方法。

后来,看了上面的文章后,自己进行了实验,发现这种方法确实可行。现在将复刻后的代码公布如下:


一、MyMessager类

这里创建个MyMessager类,对Messager信息进行监听。【类的代码如下:】

  • iOperCount,创建为public类,是为了调用的时候来进行运行时间判断。
csharp 复制代码
namespace ZHCH_winform_2.manager
{
    internal class MyMessager : IMessageFilter
    {
        public int iOperCount { get; set; }

        public bool PreFilterMessage(ref Message m)
        {
            // 如果检测到有鼠标或则键盘的消息,则使计数为0
            if(m.Msg==0x0200 || m.Msg==0x0201 || m.Msg==0x0204 || m.Msg == 0x0207)
            {
                iOperCount = 0;
            }
            return false;
        }
    }
}

二、Form中进行Timer监听

  • 初始化MyMessager类msg。
csharp 复制代码
        private MyMessager msg = new MyMessager();
        //
        public FormMain()
        {
            InitializeComponent();
            this.KeyPreview = true; // 允许窗体接收按键事件
        }
  • 在Form类FormMain加载时,进行消息监听【采用了定时器Timer,命名为:timerMoniter】
csharp 复制代码
        private void FormMain_Load(object sender, EventArgs e)
        {
            Application.AddMessageFilter(msg);
            timerMoniter.Start();
        }
  • 定时器中的监听事件如下:
csharp 复制代码
        /// <summary>
        /// 全局监控鼠标、键盘等事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerMoniter_Tick(object sender, EventArgs e)
        {
            //如果计数=0,代表触发了按钮,鼠标等事件,那么就要重新计时。
            if (msg.iOperCount == 0)
            {
                ResetLogoutSeconds();
            }
            int iOperCount = msg.iOperCount++;
            // 如果计数超过了设定的最大时间,就退出登录
            if (iOperCount > this.MaxSeconds || logoutSeconds <= 0)
            {
                MessageBox.Show($"{this.MaxSeconds}已经到达");
                Application.Exit();
            }
            // 倒计时的循环
            if (logoutSeconds > 0)
            {
                this.progressLogout.Text = logoutSeconds.ToString() + " S";
                float progressValue = (float)(logoutSeconds / MaxSeconds);
                this.progressLogout.Value = progressValue;
                logoutSeconds--;
            }
        }
        /// <summary>
        /// 重写键盘读取事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            ResetLogoutSeconds();
            //base.OnKeyDown(e);
        }
        /// <summary>
        /// 重置倒计时时间
        /// </summary>
        private void ResetLogoutSeconds()
        {
            logoutSeconds = 120;
            progressLogout.Text = logoutSeconds.ToString() + " S";
            this.progressLogout.Value = 1;
        }

更新时间

  • 2024.08.26:创建并复刻成功
相关推荐
He BianGu13 小时前
【笔记】C# 中BindingFlags的详细作用
笔记·c#
?abc!13 小时前
(贪心)621. 任务调度器
java·前端·c#
开开心心就好16 小时前
电脑小说阅读器,支持朗读和自定义皮肤
服务器·开发语言·javascript·算法·pdf·c#·音视频
淡海水17 小时前
07-06-源码-.NET Core GC的极致优化技术
unity·架构·c#·.netcore·gc·1024程序员节
万化冥合18 小时前
怎么批量把 Word 转 PDF?
python·pdf·c#·word
淡海水1 天前
07-02-源码-.NET Core GC分配路径
算法·unity·c#·.netcore·gc·1024程序员节
吴可可1231 天前
C#调用摄像头拍照的三种API方案
c#
Msir_Modern2 天前
Noita 元胞沙盒笔记
算法·unity·c#·游戏引擎·元胞自动机
星之擎2 天前
Task 很优雅的取消方式是什么?C# 里面。
开发语言·c#
霍霍的袁2 天前
【C++11】左值右值引用与移动语义详细笔记(左值右值、右值引用、移动构造、移动赋值、引用折叠、万能转发)
c++·笔记·学习·visual studio