|
|
@@ -45,6 +45,13 @@ void CTouchWindowBase::SynthesizeTap(HWND target, POINT pt)
|
|
|
::PostMessage(target, WM_LBUTTONUP, 0, lParamPos);
|
|
|
}
|
|
|
|
|
|
+void CTouchWindowBase::ScheduleHoverClear()
|
|
|
+{
|
|
|
+ // 见下方 WM_TIMER(HOVER_CLEAR_TIMER_ID)说明。ExtraInfo=0 的鼠标消息不会被
|
|
|
+ // MessageHandler 入口的 FROMTOUCH 过滤器吞掉,能正常进入 DuiLib 的悬停清理逻辑。
|
|
|
+ ::SetTimer(m_hWnd, HOVER_CLEAR_TIMER_ID, HOVER_CLEAR_DELAY_MS, NULL);
|
|
|
+}
|
|
|
+
|
|
|
void CTouchWindowBase::StartInertia(float velocityPxPerMs)
|
|
|
{
|
|
|
if (m_inertiaActive)
|
|
|
@@ -215,6 +222,18 @@ LRESULT CTouchWindowBase::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
|
|
// 启动惯性滚动(如果速度足够大)
|
|
|
StartInertia(velocityPxPerMs);
|
|
|
+
|
|
|
+ // 关键修复(悬浮态卡死):触屏轻触/滑动时,操作系统会先发一条
|
|
|
+ // “将光标移动到触点”的 WM_MOUSEMOVE(不带 FROMTOUCH 标记),它绕过了
|
|
|
+ // MessageHandler 入口的过滤器,于是 DuiLib 会把该控件置为 UISTATE_HOT
|
|
|
+ // (悬浮态);而 DuiLib 只在 WM_MOUSEMOVE 指到“别的控件/窗口外”时才
|
|
|
+ // 发 MOUSELEAVE 清除悬浮态。触屏没有后续“移动光标离开”的动作,于是
|
|
|
+ // 悬浮态永远清不掉 → 按钮/列表项卡在悬浮态不恢复。
|
|
|
+ // 真实鼠标靠“物理移开”触发 MOUSELEAVE;这里用定时器在手势结束后补一次
|
|
|
+ // WM_MOUSEMOVE(-1)(即“光标移到窗口外”),模拟鼠标移开,强制清除悬浮态。
|
|
|
+ // 用定时器延后约 50ms,确保本次手势可能产生的 OS 尾随消息都已处理完,
|
|
|
+ // 避免“我们刚清掉又被 OS 尾随的 move 重新置上”的竞态。
|
|
|
+ ScheduleHoverClear();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -229,6 +248,18 @@ LRESULT CTouchWindowBase::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
|
|
case WM_TIMER:
|
|
|
{
|
|
|
+ if (wParam == HOVER_CLEAR_TIMER_ID)
|
|
|
+ {
|
|
|
+ // 模拟“鼠标移开窗口”:给 paint 窗口发一条 WM_MOUSEMOVE,lParam=-1 表示
|
|
|
+ // 坐标为 (-1,-1),FindControl 必然返回 NULL;DuiLib 在 WM_MOUSEMOVE 里对旧
|
|
|
+ // 悬停控件触发 UIEVENT_MOUSELEAVE,从而清除 UISTATE_HOT 悬浮态。
|
|
|
+ // 这样触屏轻触/滑动结束后,按钮/列表项不会卡在悬浮态。
|
|
|
+ HWND target = m_hWndPaint ? m_hWndPaint : m_hWnd;
|
|
|
+ if (target && ::IsWindow(target))
|
|
|
+ ::PostMessage(target, WM_MOUSEMOVE, 0, (LPARAM)-1);
|
|
|
+ ::KillTimer(m_hWnd, HOVER_CLEAR_TIMER_ID);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
if (wParam == INERTIA_TIMER_ID && m_inertiaActive)
|
|
|
{
|
|
|
HWND target = m_hWndPaint ? m_hWndPaint : m_hWnd;
|
|
|
@@ -273,6 +304,7 @@ LRESULT CTouchWindowBase::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
|
|
case WM_DESTROY:
|
|
|
StopInertia();
|
|
|
+ ::KillTimer(m_hWnd, HOVER_CLEAR_TIMER_ID);
|
|
|
break;
|
|
|
}
|
|
|
|