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

目录


前言

参考文章:
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:创建并复刻成功
相关推荐
Kookoos1 天前
ABP + ClickHouse 实时 OLAP:物化视图与写入聚合
clickhouse·c#·linq·abp vnext·实时olap
wangnaisheng1 天前
【C#】在一个任意旋转的矩形(由四个顶点定义)内绘制一个内切椭圆
c#·gdi
ghie90901 天前
C#实现OPC客户端
c#
一匹电信狗1 天前
【C++】C++11新特性第一弹(列表初始化、新式声明、范围for和STL中的变化)
服务器·开发语言·c++·leetcode·小程序·stl·visual studio
甄天1 天前
VisionPro联合编程控件导入WinFrom以及VS卡死问题
c#·visual studio·visionpro
oioihoii1 天前
VS Code C#调试完全指南
开发语言·c#·策略模式
咕白m6251 天前
使用 C# 实现 PDF 转 HTML 并自定义转换选项
c#·html
唐青枫1 天前
从 Skip Take 到 Keyset:C# 分页原理与实践
c#·.net
钢铁男儿2 天前
C# 一个投资跟踪程序的设计与实现:面向对象与设计模式的深度解析
java·设计模式·c#
技术支持者python,php2 天前
C#-mqtt通讯,服务端和客户端,以及esp32-mqtt
服务器·windows·c#