TouchWindowBase.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #pragma once
  2. #include "../pch/pch.h"
  3. #include <deque>
  4. #include <chrono>
  5. class TouchWindowBase : public DuiLib::CWindowWnd
  6. {
  7. public:
  8. TouchWindowBase();
  9. virtual ~TouchWindowBase();
  10. // 必须设置为 DuiLib 的 paint 窗口(CPaintManagerUI 创建的窗口)
  11. void SetPaintWindow(HWND hWndPaint)
  12. {
  13. m_hWndPaint = hWndPaint;
  14. }
  15. virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
  16. protected:
  17. HWND m_hWndPaint = NULL;
  18. // touch 状态
  19. bool m_touchDown = false;
  20. LONG m_lastY = 0;
  21. int m_accumWheel = 0; // 累积 wheel 值(单位 wheel delta)
  22. // 保存最后一次触摸的点(目标 paint 窗口的客户区坐标),用于惯性期间发送位置
  23. POINT m_lastTouchPt = { 0, 0 };
  24. // 每像素转多少 wheel units(可调节灵敏度)
  25. // wheelUnits = dy * PIXEL_TO_WHEEL,后面按 WHEEL_DELTA(120) 做累积阈值
  26. static constexpr float PIXEL_TO_WHEEL = 8.0f; // 约 15px -> 120,按需调整
  27. // 采样用于计算速度
  28. struct TouchSample
  29. {
  30. std::int64_t tms; // ms
  31. LONG y;
  32. };
  33. std::deque<TouchSample> m_samples; // 保留最近若干样本
  34. // 惯性滚动状态
  35. bool m_inertiaActive = false;
  36. float m_inertiaVelocityPxPerMs = 0.0f; // 像素每毫秒
  37. UINT_PTR m_inertiaTimerId = 0;
  38. std::int64_t m_lastInertiaTms = 0;
  39. // 惯性参数(可调)
  40. static constexpr int INERTIA_TIMER_ID = 0xA001;
  41. static constexpr int INERTIA_TIMER_INTERVAL_MS = 16; // 约 60 FPS
  42. // 衰减系数按每毫秒指数衰减: velocity *= pow(INERTIA_DECAY_PER_MS, dt)
  43. static constexpr float INERTIA_DECAY_PER_MS = 0.995f; // 值接近 1,越接近 1 惯性持续越久
  44. static constexpr float MIN_INERTIA_VELOCITY = 0.02f; // px/ms,低于则停止
  45. static constexpr int SAMPLE_WINDOW_MS = 120; // 计算速度时回溯的时间窗口
  46. static constexpr int MAX_SAMPLE_COUNT = 8;
  47. // 内部方法
  48. void AddTouchSample(LONG y);
  49. void StartInertia(float velocityPxPerMs);
  50. void StopInertia();
  51. std::int64_t NowMs() const;
  52. };