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