|
|
@@ -4685,6 +4685,36 @@ namespace DuiLib
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
+ case WM_NCMOUSEMOVE:
|
|
|
+ {
|
|
|
+ // ------------------------------------------------------------
|
|
|
+ // [第 48 轮] 鼠标一进入**非客户区**(标题栏 caption / 边框),
|
|
|
+ // 客户区就再也收不到 WM_MOUSEMOVE 了。而悬浮态的 enter/leave
|
|
|
+ // **只在 WM_MOUSEMOVE 里切换**(见下面 4904 那段的总闸)
|
|
|
+ // ⇒ 移进标题栏之前点亮的那颗控件会一直保持悬浮态。
|
|
|
+ //
|
|
|
+ // 为什么标题栏属于非客户区:本项目的自绘标题栏靠
|
|
|
+ // `CMainWnd::OnNcHitTest` / `CChufangSettingWnd::OnNcHitTest`
|
|
|
+ // 返回 HTCAPTION 实现拖动 —— 判据是"落在 caption 矩形内、
|
|
|
+ // 且命中控件的 class 不是 ButtonUI/OptionUI/TextUI"。
|
|
|
+ // 所以**标题栏空白区 = HTCAPTION = 非客户区**(用户复现的正是
|
|
|
+ // 从「+」按钮往右上移到标题栏空白处);标题栏上的按钮仍是
|
|
|
+ // HTCLIENT,走正常客户区消息,不受本分支影响。
|
|
|
+ //
|
|
|
+ // 判据是纯状态的 `wParam`(HTCAPTION / HTLEFT / HTTOP / …):
|
|
|
+ // 能进本 case,就已经不在客户区了,**不需要任何时间戳**。
|
|
|
+ //
|
|
|
+ // ⚠️ 必须 `return false`:这里只是在旁边补一个副作用,
|
|
|
+ // 消息本身必须继续落到 DefWindowProc —— 拖动窗口、
|
|
|
+ // 边框改尺寸全靠它,拦掉就再也拖不动窗口了。
|
|
|
+ // ------------------------------------------------------------
|
|
|
+ if (m_pEventHover != NULL || m_aNeedMouseLeaveNeeded.GetSize() > 0)
|
|
|
+ {
|
|
|
+ POINT ptNoTarget = { -1, -1 };
|
|
|
+ ClearTouchHoverState(ptNoTarget);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
case WM_MOUSELEAVE:
|
|
|
{
|
|
|
if (m_hwndTooltip != NULL) ::SendMessage(m_hwndTooltip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&m_ToolTip);
|
|
|
@@ -4758,8 +4788,32 @@ namespace DuiLib
|
|
|
// 明显移动 ⇒ 抑制期结束,落到下面走正常的鼠标移动流程。
|
|
|
}
|
|
|
|
|
|
+ // ------------------------------------------------------------
|
|
|
+ // [第 48 轮] `lParam == -1` 是"**客户区已无悬浮目标**"的哨兵。
|
|
|
+ //
|
|
|
+ // 全库产生它的地方**只有一处**:上面 WM_MOUSELEAVE 分支——
|
|
|
+ // 鼠标离开客户区时(移进标题栏 caption、或整体移出窗口),
|
|
|
+ // 系统只给一次 WM_MOUSELEAVE,那条分支就回发本哨兵。
|
|
|
+ //
|
|
|
+ // 原写法是 `break;`(1aacbb0d0 / 09-19 加)。那等于把 nim 原版
|
|
|
+ // "让 FindControl((-1,-1)) 落空 ⇒ 对 m_pEventHover 补发
|
|
|
+ // MOUSELEAVE"的收尾通道**整条掐断** ⇒ 鼠标从按钮移进标题栏
|
|
|
+ // 之后,该控件的悬浮态永不消失(主窗口与所有弹框一致复现)。
|
|
|
+ //
|
|
|
+ // 现在:哨兵仍然 break(绝不参与下面的坐标/拖拽/抑制判据——
|
|
|
+ // m_ptLastMousePos 与 s_ptLastTouchScreen 都不能被 (-1,-1)
|
|
|
+ // 污染,否则 bNeedDrag 会误判、触摸后的悬浮抑制也会被提前解除),
|
|
|
+ // 但**先把该做的收尾做掉**。
|
|
|
+ // ------------------------------------------------------------
|
|
|
if ((INT_PTR)lParam == -1)
|
|
|
+ {
|
|
|
+ if (m_pEventHover != NULL || m_aNeedMouseLeaveNeeded.GetSize() > 0)
|
|
|
+ {
|
|
|
+ POINT ptNoTarget = { -1, -1 };
|
|
|
+ ClearTouchHoverState(ptNoTarget);
|
|
|
+ }
|
|
|
break;
|
|
|
+ }
|
|
|
|
|
|
POINT ptCheck = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
|
if (s_bSuppressHoverAfterTouch)
|