// from bool QApplicationPrivate::translateTouchEvent() bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, QtWindows::WindowsEventType, MSG msg, LRESULT *) { #ifndef Q_OS_WINCE typedef QWindowSystemInterface::TouchPoint QTouchPoint; typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList; const QRect screenGeometry = window->screen()->geometry(); const int winTouchPointCount = msg.wParam; QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]); memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchPointCount); QTouchPointList touchPoints; touchPoints.reserve(winTouchPointCount); Qt::TouchPointStates allStates = 0; Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo); QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); for (int i = 0; i < winTouchPointCount; ++i) { const TOUCHINPUT &winTouchInput = winTouchInputs[i]; QTouchPoint touchPoint; touchPoint.pressure = 1.0; touchPoint.id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1); if (touchPoint.id == -1) { touchPoint.id = m_touchInputIDToTouchPointID.size(); m_touchInputIDToTouchPointID.insert(winTouchInput.dwID, touchPoint.id); } QPointF screenPos = QPointF(qreal(winTouchInput.x) / qreal(100.), qreal(winTouchInput.y) / qreal(100.)); if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA) touchPoint.area.setSize(QSizeF(qreal(winTouchInput.cxContact) / qreal(100.), qreal(winTouchInput.cyContact) / qreal(100.))); touchPoint.area.moveCenter(screenPos); if (winTouchInput.dwFlags & TOUCHEVENTF_DOWN) { touchPoint.state = Qt::TouchPointPressed; } else if (winTouchInput.dwFlags & TOUCHEVENTF_UP) { touchPoint.state = Qt::TouchPointReleased; } else { // TODO: Previous code checked" // screenPos == touchPoint.normalPosition -> Qt::TouchPointStationary, but // but touchPoint.normalPosition was never initialized? touchPoint.state = touchPoint.state; } touchPoint.normalPosition = QPointF(screenPos.x() / screenGeometry.width(), screenPos.y() / screenGeometry.height()); allStates |= touchPoint.state; touchPoints.append(touchPoint); } QWindowsContext::user32dll.closeTouchInputHandle((HANDLE) msg.lParam); // all touch points released, forget the ids we've seen, they may not be reused if (allStates == Qt::TouchPointReleased) m_touchInputIDToTouchPointID.clear(); if (!m_touchDevice) { m_touchDevice = new QTouchDevice; // TODO: Device used to be hardcoded to screen in previous code. m_touchDevice->setType(QTouchDevice::TouchScreen); m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition); QWindowSystemInterface::registerTouchDevice(m_touchDevice); } QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints); return true; #else return false; #endif }
// from bool QApplicationPrivate::translateTouchEvent() bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, QtWindows::WindowsEventType, MSG msg, LRESULT *) { typedef QWindowSystemInterface::TouchPoint QTouchPoint; typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList; if (!QWindowsContext::instance()->initTouch()) { qWarning("Unable to initialize touch handling."); return true; } const QScreen *screen = window->screen(); if (!screen) screen = QGuiApplication::primaryScreen(); if (!screen) return true; const QRect screenGeometry = screen->geometry(); const int winTouchPointCount = int(msg.wParam); QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]); memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * size_t(winTouchPointCount)); QTouchPointList touchPoints; touchPoints.reserve(winTouchPointCount); Qt::TouchPointStates allStates = 0; QWindowsContext::user32dll.getTouchInputInfo(reinterpret_cast<HANDLE>(msg.lParam), UINT(msg.wParam), winTouchInputs.data(), sizeof(TOUCHINPUT)); for (int i = 0; i < winTouchPointCount; ++i) { const TOUCHINPUT &winTouchInput = winTouchInputs[i]; int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1); if (id == -1) { id = m_touchInputIDToTouchPointID.size(); m_touchInputIDToTouchPointID.insert(winTouchInput.dwID, id); } QTouchPoint touchPoint; touchPoint.pressure = 1.0; touchPoint.id = id; if (m_lastTouchPositions.contains(id)) touchPoint.normalPosition = m_lastTouchPositions.value(id); const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) / qreal(100.); if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA) touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) / qreal(100.)); touchPoint.area.moveCenter(screenPos); QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(), screenPos.y() / screenGeometry.height()); const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition); touchPoint.normalPosition = normalPosition; if (winTouchInput.dwFlags & TOUCHEVENTF_DOWN) { touchPoint.state = Qt::TouchPointPressed; m_lastTouchPositions.insert(id, touchPoint.normalPosition); } else if (winTouchInput.dwFlags & TOUCHEVENTF_UP) { touchPoint.state = Qt::TouchPointReleased; m_lastTouchPositions.remove(id); } else { touchPoint.state = (stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved); m_lastTouchPositions.insert(id, touchPoint.normalPosition); } allStates |= touchPoint.state; touchPoints.append(touchPoint); } QWindowsContext::user32dll.closeTouchInputHandle(reinterpret_cast<HANDLE>(msg.lParam)); // all touch points released, forget the ids we've seen, they may not be reused if (allStates == Qt::TouchPointReleased) m_touchInputIDToTouchPointID.clear(); QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); return true; }