触控:WPF捕捉触控事件

1 注册触控事件

2 注册键盘事件

3 注册鼠标点击事件

4 注册鼠标滚轮事件

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace Windows
{
    /// <summary>
    /// 触控源
    /// </summary>
    public class TouchSourceCreator 
    {
        //触控界面
        private FrameworkElement _touchUi;
        private int _realScreenWidth;
        private int _realScreenHeight;
        private double _lastMoveX = Double.NaN;
        private double _lastMoveY = Double.NaN;
        //触发最小像素间隔
        private double _minimumInterval;
        // 双击时间阈值/ms
        private const int DoubleClickTimeMs = 400;
        private readonly Stopwatch _lastTouchDown = new Stopwatch();

        /// <summary>
        /// 初始化事件
        /// </summary>
        /// <param name="touchUi"></param>
        public TouchSourceCreator(FrameworkElement touchUi)
        {
            _touchUi = touchUi;
            // 注册触控事件
            touchUi.TouchDown -= CaptureTouchDown;
            touchUi.TouchDown += CaptureTouchDown;
            touchUi.TouchMove -= CaptureTouchMove;
            touchUi.TouchMove += CaptureTouchMove;
            touchUi.TouchUp -= CaptureTouchUp;
            touchUi.TouchUp += CaptureTouchUp;
            // 注册键盘事件
            if (Application.Current.MainWindow != null)
            {
                Application.Current.MainWindow.KeyDown -= CaptureKeyboardDown;
                Application.Current.MainWindow.KeyDown += CaptureKeyboardDown;
                Application.Current.MainWindow.KeyUp -= CaptureKeyboardUp;
                Application.Current.MainWindow.KeyUp += CaptureKeyboardUp;
            }
            //注册鼠标事
            touchUi.MouseLeftButtonDown -= CaptureMouseLeftButtonDown;
            touchUi.MouseLeftButtonDown += CaptureMouseLeftButtonDown;
            touchUi.MouseLeftButtonUp -= CaptureMouseLeftButtonUp;
            touchUi.MouseLeftButtonUp += CaptureMouseLeftButtonUp;
            touchUi.MouseMove -= CaptureMouseMoveEventData;
            touchUi.MouseMove += CaptureMouseMoveEventData;
            touchUi.MouseRightButtonDown -= CaptureMouseRightButtonDown;
            touchUi.MouseRightButtonDown += CaptureMouseRightButtonDown;
            touchUi.MouseRightButtonUp -= CaptureMouseRightButtonUp;
            touchUi.MouseRightButtonUp += CaptureMouseRightButtonUp;
            // 注册鼠标滚轮事件
            touchUi.MouseWheel -= CaptureMouseWheelData;
            touchUi.MouseWheel += CaptureMouseWheelData;
        }

        /// <summary>
        /// 初始化屏幕大小
        /// </summary>
        /// <returns></returns>
        public async Task<Task> InitRealScreenSizeAsync()
        {
            await Task.Delay(100);
            while (true)
            {
                _realScreenWidth = (int)_touchUi.ActualWidth;
                _realScreenHeight = (int)_touchUi.ActualHeight;
                if (_realScreenWidth == 0)
                    await Task.Delay(100);
                else
                {
                    _minimumInterval = Math.Min(_realScreenWidth, _realScreenHeight) * 0.01;
                    return Task.CompletedTask;
                }
            }
        }

        #region 触控事件

        private void CaptureTouchDown(object sender, TouchEventArgs e)
        {
            if (!CanSend) return;
            var touchPoint = e.GetTouchPoint(_touchUi);
            var eventInfo = new EventInfo
            {
                Type = 6,
                Event = 0,
                X = Math.Round(touchPoint.Position.X / _realScreenWidth, 3),
                Y = Math.Round(touchPoint.Position.Y / _realScreenHeight, 3)
            };
            _lastMoveX = touchPoint.Position.X;
            _lastMoveY = touchPoint.Position.Y;

            DeviceSource?.Invoke(eventInfo);
        }


        private void CaptureTouchUp(object sender, TouchEventArgs e)
        {
            if (!CanSend) return;
            if (_lastTouchDown.IsRunning && _lastTouchDown.ElapsedMilliseconds < DoubleClickTimeMs)
            {
                HandleDoubleClick(e);
                _lastTouchDown.Reset();
                return;
            }
            _lastTouchDown.Restart();

            var touchPoint = e.GetTouchPoint(_touchUi);
            var eventInfo = new EventInfo
            {
                Type = 6,
                Event = 1,
                X = Math.Round(touchPoint.Position.X / _realScreenWidth, 3),
                Y = Math.Round(touchPoint.Position.Y / _realScreenHeight, 3)
            };
            _lastMoveX = Double.NaN;
            _lastMoveY = Double.NaN;

            DeviceSource?.Invoke(eventInfo);
        }

        private void HandleDoubleClick(TouchEventArgs e)
        {
            var touchPoint = e.GetTouchPoint(_touchUi);
            var eventInfo = new EventInfo
            {
                Type = 7,
                Event = 1,
                X = Math.Round(touchPoint.Position.X / _realScreenWidth, 3),
                Y = Math.Round(touchPoint.Position.Y / _realScreenHeight, 3)
            };
            _lastMoveX = touchPoint.Position.X;
            _lastMoveY = touchPoint.Position.Y;

            DeviceSource?.Invoke(eventInfo);
        }

        private void CaptureTouchMove(object sender, TouchEventArgs e)
        {
            if (!CanSend) return;
            TouchPoint touchPoint = e.GetTouchPoint(_touchUi);
            var eventInfo = new EventInfo
            {
                Type = 6,
                Event = 4,
                X = Math.Round(touchPoint.Position.X / _realScreenWidth, 3),
                Y = Math.Round(touchPoint.Position.Y / _realScreenHeight, 3)
            };

            if (!double.IsNaN(_lastMoveX) && Math.Abs(_lastMoveX - touchPoint.Position.X) < _minimumInterval && Math.Abs(_lastMoveY - touchPoint.Position.Y) < _minimumInterval)
            {
                return;
            }
            _lastMoveX = touchPoint.Position.X;
            _lastMoveY = touchPoint.Position.Y;

            DeviceSource?.Invoke(eventInfo);
        }
        #endregion

        #region 鼠标事件
        private void CaptureMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!CanSend) return;
            if (e.StylusDevice != null) return;
            var eventInfo = new EventInfo
            {
                Type = 2,
                Event = 0,
                X = Math.Round(e.GetPosition(_touchUi).X / _realScreenWidth, 3),
                Y = Math.Round(e.GetPosition(_touchUi).Y / _realScreenHeight, 3)
            };

            DeviceSource?.Invoke(eventInfo);
        }
        private void CaptureMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!CanSend) return;
            if (e.StylusDevice != null) return;
            var codeType = new EventInfo
            {
                Type = 2,
                Event = 1,
                X = Math.Round(e.GetPosition(_touchUi).X / _realScreenWidth, 3),
                Y = Math.Round(e.GetPosition(_touchUi).Y / _realScreenHeight, 3)
            };

            DeviceSource?.Invoke(codeType);
        }
        private void CaptureMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!CanSend) return;
            if (e.StylusDevice != null) return;
            var eventInfo = new EventInfo
            {
                Type = 3,
                Event = 0,
                X = Math.Round(e.GetPosition(_touchUi).X / _realScreenWidth, 3),
                Y = Math.Round(e.GetPosition(_touchUi).Y / _realScreenHeight, 3)
            };

            DeviceSource?.Invoke(eventInfo);
        }
        private void CaptureMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!CanSend) return;
            if (e.StylusDevice != null) return;
            var eventInfo = new EventInfo
            {
                Type = 3,
                Event = 1,
                X = Math.Round(e.GetPosition(_touchUi).X / _realScreenWidth, 3),
                Y = Math.Round(e.GetPosition(_touchUi).Y / _realScreenHeight, 3)
            };

            DeviceSource?.Invoke(eventInfo);
        }
        private void CaptureMouseMoveEventData(object sender, MouseEventArgs e)
        {
            if (!CanSend) return;
            if (e.StylusDevice != null) return;
            var pressedMouseButton = GetPressedType(true, e);
            if (pressedMouseButton.type == 0)
            {
                return;
            }
            var eventInfo = new EventInfo
            {
                Type = pressedMouseButton.type,
                Event = pressedMouseButton.eventType,
                X = Math.Round(e.GetPosition(_touchUi).X / _realScreenWidth, 3),
                Y = Math.Round(e.GetPosition(_touchUi).Y / _realScreenHeight, 3)
            };

            DeviceSource?.Invoke(eventInfo);
        }
        private void CaptureMouseWheelData(object sender, MouseWheelEventArgs e)
        {
            var eventInfo = new EventInfo
            {
                Type = 4,
                Event = e.Delta > 0 ? 2 : 3,
                X = Math.Round(e.GetPosition(_touchUi).X / _realScreenWidth, 3),
                Y = Math.Round(e.GetPosition(_touchUi).Y / _realScreenHeight, 3)
            };

            DeviceSource?.Invoke(eventInfo);
        }

        /// <summary>
        /// 获取按压类型
        /// </summary>
        /// <param name="move"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private (int type, int eventType) GetPressedType(bool move, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                return move ? (1, 0) : (2, 0);
            }
            if (e.MiddleButton == MouseButtonState.Pressed)
            {
                return (4, 0);
            }
            if (e.RightButton == MouseButtonState.Pressed)
            {
                return (3, 0);
            }
            return (0, 0);
        }

        #endregion

        #region 键盘事件
        private void CaptureKeyboardDown(object sender, KeyEventArgs e)
        {
            if (!CanSend) return;

            int virtualKeyCode = KeyInterop.VirtualKeyFromKey(e.Key); // 转换为虚拟键码
            var eventInfo = new EventInfo
            {
                Type = 5,
                Event = 0,
                Code = virtualKeyCode,
            };

            DeviceSource?.Invoke(eventInfo);
        }

        private void CaptureKeyboardUp(object sender, KeyEventArgs e)
        {
            if (!CanSend) return;
            int virtualKeyCode = KeyInterop.VirtualKeyFromKey(e.Key); // 转换为虚拟键码
            var eventInfo = new EventInfo
            {
                Type = 5,
                Event = 1,
                Code = virtualKeyCode,
            };

            DeviceSource?.Invoke(eventInfo);
        }
        #endregion

        private bool CanSend => _realScreenWidth != 0;

        /// <summary>
        /// 设备触发
        /// </summary>
        public event Action<EventInfo> DeviceSource;
    }
}

 

posted on 2024-03-04 19:31  TanZhiWei  阅读(137)  评论(0编辑  收藏  举报