C#开发winform&wpf后台捕获鼠标移动事件

做 WPF和winform的时候,可以在界面上设置鼠标移动事件来检测鼠标移动,如果项目为后期改造这样做的话改动量很大,今天通过另外一种后台调用windows api的方式进行快速捕获和触发,提高开发效率分享给大家。

csharp 复制代码
  /// <summary>
    /// 鼠标移动帮助类
    /// </summary>
    public class MouseMoveHelper:IDisposable
    {
        public MouseMoveHelper()
        {

        }

        public void Dispose()
        {
            try
            {
                if (mousePositionTimer != null)
                {
                    mousePositionTimer.Stop();
                    deactivatedTimer.Stop();
                    mousePositionTimer = null;
                    deactivatedTimer = null;
                }
            }
            catch (Exception ex)
            {

            }
        }

        public Action<NoOperationEvent> OK;


        #region 监测是否有用户操作

        private DispatcherTimer mousePositionTimer;    //长时间不操作该程序退回到登录界面的计时器
        private Point mousePosition;    //鼠标的位置
        private int checkCount = 0;   //检测鼠标位置的次数

        private DispatcherTimer deactivatedTimer;   //当焦点不在此程序上时计时器


        public void Start()
        {
            mousePosition = GetMousePoint();  //获取鼠标坐标

            if (mousePositionTimer==null)
            {
                mousePositionTimer = new DispatcherTimer();
                mousePositionTimer.Tick += new EventHandler(MousePositionTimedEvent);
                mousePositionTimer.Interval = new TimeSpan(0, 0, 1);     //每隔10秒检测一次鼠标位置是否变动
            }
            mousePositionTimer.Start();
            if (deactivatedTimer == null)
            {
                deactivatedTimer = new DispatcherTimer();
                deactivatedTimer.Tick += new EventHandler(deactivatedTimer_Tick);
                deactivatedTimer.Interval = new TimeSpan(0, 0, 10);   //如果焦点不在此程序中时,过10s程序自动重启
            }
        }

        bool isMoved = true;
        // 倒计时延迟数
        int maxDelayCount = 1;

        private void MousePositionTimedEvent(object sender, EventArgs e)
        {
            
            if (!HaveUsedTo())
            {
                checkCount++;    //检测到鼠标没移动,checkCount + 1  
                if (checkCount == maxDelayCount)
                {
                    checkCount = 0;
                    //长时间无人操作
                    if (isMoved)
                    {
                        isMoved = false;
                        OK?.Invoke(new NoOperationEvent() { Message = "检测到无鼠标移动", CurrentMouseState = NoOperationEvent.MouseState.standstill });
                    }
                }
            }
            else
            {
                OK?.Invoke(new NoOperationEvent() { Message = "检测到鼠标移动", CurrentMouseState = NoOperationEvent.MouseState.move });
                checkCount = 0;     //检测到鼠标移动,重新计数
                isMoved=true;
            }
        }

        private void deactivatedTimer_Tick(object sender, EventArgs e)
        {
            deactivatedTimer.Stop();
            //长时间无人操作
            //Messenger.Default.Send<string>("focus", "DoFocus");
        }


        //判断鼠标是否移动
        private bool HaveUsedTo()
        {
            Point point = GetMousePoint();
            if (point == mousePosition)
            {
                return false;
            }
            mousePosition = point;
            return true;
        }


        [StructLayout(LayoutKind.Sequential)]
        private struct MPoint
        {
            public int X;
            public int Y;

            public MPoint(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern bool GetCursorPos(out MPoint mpt);

        /// 获取当前屏幕鼠标位置   
        public Point GetMousePoint()
        {
            MPoint mpt = new MPoint();
            GetCursorPos(out mpt);
            Point p = new Point(mpt.X, mpt.Y);
            return p;
        }

        
        #endregion
    }

程序调用

csharp 复制代码
            var MouseMoveHelper = new MouseMoveHelper();
            MouseMoveHelper.OK = CheckMouseState;
             MouseMoveHelper.Start();

一般在顶级父类里面初始化的时候进行处理即可

相关推荐
samble5 小时前
从零搭建灌装监控系统(十):生产追溯,条码触发自动记录
c#·wpf·mvvm·modbus·工业控制
czhc11400756639 小时前
退出防呆:用“总闸“收口所有退出入口,以及三个并发语法坑
开发语言·c#
淡海水12 小时前
02-01-原理篇-Mark-Sweep与变种算法
算法·unity·c#·游戏引擎·.net·gc
励志不掉头发的内向程序员15 小时前
【从零写一个CAD 04】中键拖动平移:抓住一个点,让它一直待在鼠标底下
开发语言·c++·qt·学习·系统架构·计算机外设
UIU11415 小时前
同一个变量在两个 .c 文件里类型不一致,程序会怎样?
c++·学习·c#
波力海苔夹心脆6751 天前
C# 值类型与引用类型详解:存储位置、赋值机制、参数传递、相等比较、装箱拆箱与常见陷阱
开发语言·jvm·经验分享·笔记·c#·.net
估值探索者1 天前
【Python量化策略实战 #02】多因子合成mom和vol两因子打分合成
开发语言·c++·python·数据挖掘·c#
你挚爱的强哥1 天前
【sgKeyboard】自定义组件:虚拟键盘
前端·javascript·计算机外设
淡海水2 天前
01-04-认知篇-Unity内存全景
unity·c#·游戏引擎·.net·gc
淡海水2 天前
01-03-认知篇-C#内存模型深度解析
unity·c#·游戏引擎·.net·gc