触控: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; } }