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

目录


前言

参考文章:
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:创建并复刻成功
相关推荐
玩泥巴的7 小时前
飞书 .NET SDK 事件处理的幂等性与去重机制
c#·.net·二次开发·飞书
在路上看风景7 小时前
3.2 FileStream
c#
zwm2698888157 小时前
6号楼 部分声光24v电压达不到,显示11v
c#
椒颜皮皮虾12 小时前
TensorRtSharp:在 C# 世界中释放 GPU 推理的极致性能
c#·tensorrt
行止9512 小时前
WinForms 彻底隐藏 滚动条的终极解决方案
c#
无限进步_12 小时前
【C语言&数据结构】对称二叉树:镜像世界的递归探索
c语言·开发语言·数据结构·c++·git·算法·visual studio
bugcome_com12 小时前
WPF样式进阶实战:外置样式+MVVM主题切换+样式优先级全解析
c#·.net·wpf
时光追逐者13 小时前
TIOBE 公布 C# 是 2025 年度编程语言
开发语言·c#·.net·.net core·tiobe
观无13 小时前
固高运动控制卡(GST800)基础应用分享
c#
flysh0514 小时前
如何利用 C# 内置的 Action 和 Func 委托
开发语言·c#