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

目录


前言

参考文章:
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:创建并复刻成功
相关推荐
楠楠子呀24 分钟前
独立站聊天转化全链路:从二维码引流到数据复盘
java·javascript·数据仓库·python·c#·自动化·etl
csdn_aspnet1 小时前
C# 第k个最小元素(K’th Smallest Element)
算法·c#·排序算法
影寂ldy2 小时前
Modbus-ASCII 协议 + LRC校验
笔记·网络协议·c#
自己的九又四分之三站台2 小时前
C# 接入 RasterLite2:从原生 DLL 加载到 Coverage、Section、Tile 验证
开发语言·c#·地理信息
好名字都被猪取了-2 小时前
# C# 全栈开发资源包(.NET8/.NET10)
c#
淡海水4 小时前
03-05-线性-Array-List-LinkedList与Span-所有权与成本模型选型
c#·list·编译·array·clr·机器码
瓜皮弟子头很铁4 小时前
使用c#程序打开windows软件
c#
一个帅气昵称啊4 小时前
.Net C# AI智能体开发-AI智能体
人工智能·c#·.net
李高钢1 天前
C# WinForms 架构与项目实战:多窗体通信、三层架构、数据库、日志与配置
架构·c#·winforms
OPEN-F1 天前
Python进阶教程:自动化办公实战
python·c#·自动化