|
@@ -36,7 +36,6 @@ namespace DuiLib
|
|
|
#ifndef WM_TOUCH
|
|
#ifndef WM_TOUCH
|
|
|
#define WM_TOUCH 0x0240
|
|
#define WM_TOUCH 0x0240
|
|
|
#endif
|
|
#endif
|
|
|
-
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
|
// [触屏诊断] 保留日志入口以便后续定位,但当前默认关闭。
|
|
// [触屏诊断] 保留日志入口以便后续定位,但当前默认关闭。
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
@@ -44,7 +43,7 @@ namespace DuiLib
|
|
|
{
|
|
{
|
|
|
inline bool Enabled()
|
|
inline bool Enabled()
|
|
|
{
|
|
{
|
|
|
- return false;
|
|
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 极简 TCHAR* → UTF-8 char* 转换(仅用于日志路径;非线程安全,够用即可)
|
|
// 极简 TCHAR* → UTF-8 char* 转换(仅用于日志路径;非线程安全,够用即可)
|
|
@@ -735,8 +734,13 @@ namespace DuiLib
|
|
|
if (m_hWndPaint == NULL || !::IsWindow(m_hWndPaint)) return;
|
|
if (m_hWndPaint == NULL || !::IsWindow(m_hWndPaint)) return;
|
|
|
|
|
|
|
|
TouchApi::PFN_RegisterTouchWindow pfnRegister = TouchApi::GetRegisterTouchWindow();
|
|
TouchApi::PFN_RegisterTouchWindow pfnRegister = TouchApi::GetRegisterTouchWindow();
|
|
|
|
|
+ BOOL bRegistered = FALSE;
|
|
|
if (pfnRegister != NULL)
|
|
if (pfnRegister != NULL)
|
|
|
- pfnRegister(m_hWndPaint, 0);
|
|
|
|
|
|
|
+ bRegistered = pfnRegister(m_hWndPaint, 0);
|
|
|
|
|
+ TouchTrace::Log(_T("REGISTER hwnd=%p manager=%p result=%d error=%u style=0x%08X ex=0x%08X"),
|
|
|
|
|
+ (void*)m_hWndPaint, (void*)this, (int)bRegistered, bRegistered ? 0u : ::GetLastError(),
|
|
|
|
|
+ (unsigned)::GetWindowLong(m_hWndPaint, GWL_STYLE),
|
|
|
|
|
+ (unsigned)::GetWindowLong(m_hWndPaint, GWL_EXSTYLE));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CPaintManagerUI::OnTouchInput(WPARAM wParam, LPARAM lParam)
|
|
void CPaintManagerUI::OnTouchInput(WPARAM wParam, LPARAM lParam)
|
|
@@ -1017,6 +1021,7 @@ namespace DuiLib
|
|
|
|
|
|
|
|
m_pEventTouch = NULL;
|
|
m_pEventTouch = NULL;
|
|
|
m_pTouchScrollContainer = NULL;
|
|
m_pTouchScrollContainer = NULL;
|
|
|
|
|
+ m_bSuppressPromotedTouchMouse = true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1622,14 +1627,26 @@ namespace DuiLib
|
|
|
bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes)
|
|
bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes)
|
|
|
{
|
|
{
|
|
|
if (m_hWndPaint == NULL) return false;
|
|
if (m_hWndPaint == NULL) return false;
|
|
|
|
|
+ if (uMsg == WM_TOUCH || uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
|
|
|
|
|
+ {
|
|
|
|
|
+ TouchTrace::Log(_T("MANAGER-MSG hwnd=%p manager=%p msg=0x%04X w=0x%p l=0x%p touch=%p suppress=%d"),
|
|
|
|
|
+ (void*)m_hWndPaint, (void*)this, uMsg, (void*)wParam, (void*)lParam,
|
|
|
|
|
+ (void*)m_pEventTouch, (int)m_bSuppressPromotedTouchMouse);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 触摸点击由 WM_TOUCH 直接驱动 BUTTONDOWN/BUTTONUP。
|
|
|
|
|
- // 部分收银机仍会补发鼠标消息,但这些消息不能再次进入普通鼠标状态机,
|
|
|
|
|
- // 否则会造成重复点击或覆盖触摸手势状态。
|
|
|
|
|
- if ((uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK)
|
|
|
|
|
- && IsPromotedTouchMouseMessage())
|
|
|
|
|
|
|
+ // 触摸点击优先由 WM_TOUCH 状态机驱动 BUTTONDOWN/BUTTONUP。
|
|
|
|
|
+ // 只有当前 manager 已经收到本次 WM_TOUCH,或刚刚完成了触摸点击,
|
|
|
|
|
+ // 才拦截随后提升的鼠标消息。不能仅凭 FROMTOUCH 标记无条件拦截,
|
|
|
|
|
+ // 因为部分模态窗口只收到 Windows 提升的鼠标消息而没有收到 WM_TOUCH,
|
|
|
|
|
+ // 无条件拦截会导致模态窗口完全无法触摸点击。
|
|
|
|
|
+ if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK)
|
|
|
{
|
|
{
|
|
|
- return true;
|
|
|
|
|
|
|
+ if (m_pEventTouch != NULL || m_bSuppressPromotedTouchMouse)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK)
|
|
|
|
|
+ m_bSuppressPromotedTouchMouse = false;
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// [触屏兼容] 不再过滤 Windows 为触摸模拟的鼠标消息(MOUSEEVENTF_FROMTOUCH)。
|
|
// [触屏兼容] 不再过滤 Windows 为触摸模拟的鼠标消息(MOUSEEVENTF_FROMTOUCH)。
|
|
@@ -2430,7 +2447,7 @@ namespace DuiLib
|
|
|
m_pEventClick != NULL ? m_pEventClick->GetName().GetData() : _T("null"));
|
|
m_pEventClick != NULL ? m_pEventClick->GetName().GetData() : _T("null"));
|
|
|
// WM_TOUCH 后 Windows 可能补发 WM_LBUTTONDOWN。触摸点击由 TOUCHUP
|
|
// WM_TOUCH 后 Windows 可能补发 WM_LBUTTONDOWN。触摸点击由 TOUCHUP
|
|
|
// 的 tap 判定统一处理,不能让这条合成消息提前建立鼠标点击状态。
|
|
// 的 tap 判定统一处理,不能让这条合成消息提前建立鼠标点击状态。
|
|
|
- if (m_pEventTouch != NULL)
|
|
|
|
|
|
|
+ if (m_pEventTouch != NULL || m_bSuppressPromotedTouchMouse)
|
|
|
break;
|
|
break;
|
|
|
// We alway set focus back to our app (this helps
|
|
// We alway set focus back to our app (this helps
|
|
|
// when Win32 child windows are placed on the dialog
|
|
// when Win32 child windows are placed on the dialog
|
|
@@ -2441,8 +2458,23 @@ namespace DuiLib
|
|
|
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
|
m_ptLastMousePos = pt;
|
|
m_ptLastMousePos = pt;
|
|
|
CControlUI* pControl = FindControl(pt);
|
|
CControlUI* pControl = FindControl(pt);
|
|
|
- if (pControl == NULL) break;
|
|
|
|
|
- if (pControl->GetManager() != this) break;
|
|
|
|
|
|
|
+ if (pControl == NULL)
|
|
|
|
|
+ {
|
|
|
|
|
+ TouchTrace::Log(_T("LBUTTONDOWN no control hwnd=%p pt=%d,%d root=%p"),
|
|
|
|
|
+ (void*)m_hWndPaint, pt.x, pt.y, (void*)m_pRoot);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (pControl->GetManager() != this)
|
|
|
|
|
+ {
|
|
|
|
|
+ TouchTrace::Log(_T("LBUTTONDOWN foreign control hwnd=%p pt=%d,%d name=%s manager=%p self=%p"),
|
|
|
|
|
+ (void*)m_hWndPaint, pt.x, pt.y, pControl->GetName().GetData(),
|
|
|
|
|
+ (void*)pControl->GetManager(), (void*)this);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ TouchTrace::Log(_T("LBUTTONDOWN hit hwnd=%p name=%s class=%s pos=%d,%d,%d,%d enabled=%d visible=%d"),
|
|
|
|
|
+ (void*)m_hWndPaint, pControl->GetName().GetData(), pControl->GetClass(),
|
|
|
|
|
+ pControl->GetPos().left, pControl->GetPos().top, pControl->GetPos().right, pControl->GetPos().bottom,
|
|
|
|
|
+ (int)pControl->IsEnabled(), (int)pControl->IsVisible());
|
|
|
|
|
|
|
|
// 准备拖拽
|
|
// 准备拖拽
|
|
|
if (m_bDragDrop && pControl->IsDragEnabled())
|
|
if (m_bDragDrop && pControl->IsDragEnabled())
|
|
@@ -2506,8 +2538,11 @@ namespace DuiLib
|
|
|
const bool bPromotedTouchUp = IsPromotedTouchMouseMessage();
|
|
const bool bPromotedTouchUp = IsPromotedTouchMouseMessage();
|
|
|
// TOUCHUP 已经负责 tap/drag 判定;若提升的鼠标抬起先到,不能
|
|
// TOUCHUP 已经负责 tap/drag 判定;若提升的鼠标抬起先到,不能
|
|
|
// 绕过该判定触发 BUTTONUP。
|
|
// 绕过该判定触发 BUTTONUP。
|
|
|
- if (m_pEventTouch != NULL)
|
|
|
|
|
|
|
+ if (m_pEventTouch != NULL || m_bSuppressPromotedTouchMouse)
|
|
|
|
|
+ {
|
|
|
|
|
+ m_bSuppressPromotedTouchMouse = false;
|
|
|
break;
|
|
break;
|
|
|
|
|
+ }
|
|
|
POINT ptButtonUp = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
POINT ptButtonUp = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
|
if (!bPromotedTouchUp)
|
|
if (!bPromotedTouchUp)
|
|
|
{
|
|
{
|
|
@@ -2536,6 +2571,8 @@ namespace DuiLib
|
|
|
m_bTouchMoved = false; // 用完即清,绝不影响后续真实鼠标点击
|
|
m_bTouchMoved = false; // 用完即清,绝不影响后续真实鼠标点击
|
|
|
if (pClick == NULL)
|
|
if (pClick == NULL)
|
|
|
{
|
|
{
|
|
|
|
|
+ TouchTrace::Log(_T("LBUTTONUP no click hwnd=%p pt=%d,%d"),
|
|
|
|
|
+ (void*)m_hWndPaint, pt.x, pt.y);
|
|
|
ReleaseCapture();
|
|
ReleaseCapture();
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|