Browse Source

继续修复duilib库

张洋 4 weeks ago
parent
commit
8d03c28643
3 changed files with 12 additions and 21 deletions
  1. 5 16
      DuiLib/Core/UIControl.cpp
  2. 5 3
      DuiLib/Core/UIManager.cpp
  3. 2 2
      DuiLib/Core/UIManager.h

+ 5 - 16
DuiLib/Core/UIControl.cpp

@@ -843,22 +843,11 @@ namespace DuiLib
 
 
 	void CControlUI::DoEvent(TEventUI& event)
 	void CControlUI::DoEvent(TEventUI& event)
 	{
 	{
-		// [NIM 触屏模型] 触摸事件归一化。
-		// CPaintManagerUI 把 WM_TOUCH 解析成真正的 UIEVENT_TOUCH* 事件并派发到本控件,
-		// 这里把按下/抬起归一化为等价鼠标事件,使所有既有控件(按钮、列表项、Edit、Combo
-		// 以及 60+ 窗口里的自定义控件)无需逐个改写即可原生响应手指操作。
-		//
-		// 这与已废弃的 SynthesizeTap 有本质区别:
-		//   SynthesizeTap = 向窗口句柄 PostMessage 伪造鼠标消息,要绕 Windows 消息队列,
-		//                   在模态弹框里会被路由吞掉导致点击丢失;
-		//   归一化       = 进程内直接换用事件类型后交给控件自己处理,不经消息队列,
-		//                   主窗口与弹框行为完全一致。
-		// 注意:UIEVENT_TOUCHMOVE 不在此归一化,它由 CContainerUI 单独处理为跟手滚动,
-		//     并经本函数末尾的父链冒泡抵达那里。
-		if (event.Type == UIEVENT_TOUCHDOWN)
-			event.Type = UIEVENT_BUTTONDOWN;
-		else if (event.Type == UIEVENT_TOUCHUP)
-			event.Type = UIEVENT_BUTTONUP;
+		// [NIM 触屏模型] 触摸按下/抬起的"归一化"已上移到 CPaintManagerUI::OnTouchInput:
+		// 在那里就把 WM_TOUCH 直接派发成等价鼠标事件 UIEVENT_BUTTONDOWN / UIEVENT_BUTTONUP,
+		// 这样无论控件是否重写了 DoEvent(CButtonUI 等绝大多数控件都重写了),
+		// 都能正确收到鼠标语义的事件并原生响应手指操作,无需逐个改写。
+		// 唯一保留的触摸事件是 UIEVENT_TOUCHMOVE,由 CContainerUI::DoEvent 单独处理成 1:1 跟手滚动。
 
 
 		if (event.Type == UIEVENT_SETCURSOR)
 		if (event.Type == UIEVENT_SETCURSOR)
 		{
 		{

+ 5 - 3
DuiLib/Core/UIManager.cpp

@@ -619,7 +619,8 @@ namespace DuiLib
 				if (m_pTouchTarget != NULL)
 				if (m_pTouchTarget != NULL)
 				{
 				{
 					TEventUI event = { 0 };
 					TEventUI event = { 0 };
-					event.Type = UIEVENT_TOUCHDOWN;
+					// 归一化:直接派发等价鼠标按下事件,使重写了 DoEvent 的控件(CButtonUI 等)也能原生响应手指。
+					event.Type = UIEVENT_BUTTONDOWN;
 					event.pSender = m_pTouchTarget;
 					event.pSender = m_pTouchTarget;
 					event.ptMouse = pt;
 					event.ptMouse = pt;
 					event.dwTimestamp = ::GetTickCount();
 					event.dwTimestamp = ::GetTickCount();
@@ -682,7 +683,8 @@ namespace DuiLib
 				if (m_pTouchTarget != NULL)
 				if (m_pTouchTarget != NULL)
 				{
 				{
 					TEventUI event = { 0 };
 					TEventUI event = { 0 };
-					event.Type = UIEVENT_TOUCHUP;
+					// 归一化:直接派发等价鼠标抬起事件(MOVE 仍保持 UIEVENT_TOUCHMOVE 留给 CContainerUI 滚动)。
+					event.Type = UIEVENT_BUTTONUP;
 					event.pSender = m_pTouchTarget;
 					event.pSender = m_pTouchTarget;
 					event.ptMouse = ptUp;
 					event.ptMouse = ptUp;
 					event.dwTimestamp = ::GetTickCount();
 					event.dwTimestamp = ::GetTickCount();
@@ -1269,7 +1271,7 @@ namespace DuiLib
 		//   * 滑动时经过的每个商品 item 都被置上悬浮态(UISTATE_HOT) 且无人清除 —— 多个 item 同时悬浮;
 		//   * 滑动时经过的每个商品 item 都被置上悬浮态(UISTATE_HOT) 且无人清除 —— 多个 item 同时悬浮;
 		//   * 抬起后悬浮态卡死不消失。
 		//   * 抬起后悬浮态卡死不消失。
 		// 触摸手势的实际处理(跟手滚动 / 轻触点击)由 CPaintManagerUI 通过 WM_TOUCH 完成,
 		// 触摸手势的实际处理(跟手滚动 / 轻触点击)由 CPaintManagerUI 通过 WM_TOUCH 完成,
-		// 派发给控件的 UIEVENT_TOUCHDOWN/TOUCHUP;控件自行判断是否 Activate() 触发 click,
+		// 派发成等价鼠标事件 UIEVENT_BUTTONDOWN/BUTTONUP 交给控件;控件按原生鼠标语义判定 Activate() 触发 click,
 // 全程不再合成任何鼠标消息(旧的 SynthesizeTap 方案已废弃)。
 // 全程不再合成任何鼠标消息(旧的 SynthesizeTap 方案已废弃)。
 		//
 		//
 		// 作用域天然正确:只有调用过 RegisterTouchWindow 的窗口(所有窗口已在 CPaintManagerUI::Init 注册)才会产生带
 		// 作用域天然正确:只有调用过 RegisterTouchWindow 的窗口(所有窗口已在 CPaintManagerUI::Init 注册)才会产生带

+ 2 - 2
DuiLib/Core/UIManager.h

@@ -471,9 +471,9 @@ namespace DuiLib {
 
 
 		// 触屏支持(NIM Duilib 模型,库级统一接管:主窗口 + 所有弹框通用)。
 		// 触屏支持(NIM Duilib 模型,库级统一接管:主窗口 + 所有弹框通用)。
 		// WM_TOUCH 在 MessageHandler 里被解析为真正的 DuiLib 触摸事件,直接派发给命中的控件:
 		// WM_TOUCH 在 MessageHandler 里被解析为真正的 DuiLib 触摸事件,直接派发给命中的控件:
-		//   DOWN → UIEVENT_TOUCHDOWN  控件自行处理按下(按钮置 PUSHED/CAPTURED)
+		//   DOWN → UIEVENT_BUTTONDOWN(归一化) 控件按原生鼠标语义处理按下(按钮置 PUSHED/CAPTURED)
 		//   MOVE → UIEVENT_TOUCHMOVE  经 DoEvent 冒泡链由 CContainerUI 接收,做 1:1 跟手平移
 		//   MOVE → UIEVENT_TOUCHMOVE  经 DoEvent 冒泡链由 CContainerUI 接收,做 1:1 跟手平移
-		//   UP   → UIEVENT_TOUCHUP    控件自行处理抬起(按钮 PtInRect 通过才 Activate → click)
+		//   UP   → UIEVENT_BUTTONUP(归一化)   控件按原生鼠标语义处理抬起(按钮 PtInRect 通过才 Activate → click)
 		// 全程不合成任何鼠标消息(已废弃 SynthesizeTap):点击由控件 Activate()+SendNotify 直接产生,
 		// 全程不合成任何鼠标消息(已废弃 SynthesizeTap):点击由控件 Activate()+SendNotify 直接产生,
 		// 不经过 Windows 消息队列,所以主窗口与模态弹框行为完全一致。
 		// 不经过 Windows 消息队列,所以主窗口与模态弹框行为完全一致。
 		// 注册在 Init 中完成,无需逐窗口样板,也无需 CTouchWindowBase 外挂。
 		// 注册在 Init 中完成,无需逐窗口样板,也无需 CTouchWindowBase 外挂。