QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) dh->Drop(pDataObj, reinterpret_cast<POINT*>(&pt), *pdwEffect); qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window << "keys=" << grfKeyState << "pt=" << pt.x << ',' << pt.y; m_lastPoint = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y)); // grfKeyState does not all ways contain button state in the drop QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(m_lastKeyState); QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState); QWindowsDrag *windowsDrag = QWindowsDrag::instance(); const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(), m_lastPoint, translateToQDragDropActions(*pdwEffect)); QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState); m_lastKeyState = grfKeyState; if (response.isAccepted()) { const Qt::DropAction action = response.acceptedAction(); if (action == Qt::MoveAction || action == Qt::TargetMoveAction) { if (action == Qt::MoveAction) m_chosenEffect = DROPEFFECT_MOVE; else m_chosenEffect = DROPEFFECT_COPY; HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD)); if (hData) { DWORD *moveEffect = reinterpret_cast<DWORD *>(GlobalLock(hData)); *moveEffect = DROPEFFECT_MOVE; GlobalUnlock(hData); STGMEDIUM medium; memset(&medium, 0, sizeof(STGMEDIUM)); medium.tymed = TYMED_HGLOBAL; medium.hGlobal = hData; FORMATETC format; format.cfFormat = CLIPFORMAT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)); format.tymed = TYMED_HGLOBAL; format.ptd = 0; format.dwAspect = 1; format.lindex = -1; windowsDrag->dropDataObject()->SetData(&format, &medium, true); } } else { m_chosenEffect = translateToWinDragEffects(action); } } else { m_chosenEffect = DROPEFFECT_NONE; } *pdwEffect = m_chosenEffect; windowsDrag->releaseDropDataObject(); return NOERROR; }
void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &point, LPDWORD pdwEffect) { Q_ASSERT(window); m_lastPoint = point; m_lastKeyState = grfKeyState; QWindowsDrag *windowsDrag = QWindowsDrag::instance(); const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect); QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState); QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState); const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions); m_answerRect = response.answerRect(); const Qt::DropAction action = response.acceptedAction(); if (response.isAccepted()) { m_chosenEffect = translateToWinDragEffects(action); } else { m_chosenEffect = DROPEFFECT_NONE; } *pdwEffect = m_chosenEffect; qCDebug(lcQpaMime) << __FUNCTION__ << m_window << windowsDrag->dropData() << " supported actions=" << actions << " mods=" << QGuiApplicationPrivate::modifier_buttons << " mouse=" << QGuiApplicationPrivate::mouse_buttons << " accepted: " << response.isAccepted() << action << m_answerRect << " effect" << *pdwEffect; }
bool QDragManager::drag( QDragObject * o, QDragObject::DragMode mode ) { #ifdef DEBUG_QDND_SRC qDebug( "QDragManager::drag ( %p, %d )", o, mode ); #endif if ( object == o || !o || !o->parent() ) return false; if ( object ) { cancel(); qApp->removeEventFilter( this ); beingCancelled = false; } object = o; drag_mode = mode; updatePixmap(); willDrop = FALSE; #ifndef QT_NO_ACCESSIBILITY QAccessible::updateAccessibility( this, 0, QAccessible::DragDropStart ); #endif DWORD dwEffect, dwOKEffect; QOleDataObject *obj = new QOleDataObject( o ); QOleDropSource *qsrc = new QOleDropSource(); src = o->target(); dwOKEffect = translateToWinDragEffects ( mode ); updateCursor(); #ifdef Q_OS_TEMP HRESULT r = 0; resultEffect = 0; #else HRESULT r = DoDragDrop( obj, qsrc, dwOKEffect, &dwEffect ); #endif #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); restoreCursor = false; #endif // clean up obj->releaseQt(); obj->Release(); // Will delete obj if refcount becomes 0 qsrc->Release(); // Will delete src if refcount becomes 0 object = 0; #ifndef QT_NO_ACCESSIBILITY QAccessible::updateAccessibility( this, 0, QAccessible::DragDropEnd ); #endif return true; }
Qt::DropAction QWindowsDrag::drag(QDrag *drag) { // TODO: Accessibility handling? QMimeData *dropData = drag->mimeData(); Qt::DropAction dragResult = Qt::IgnoreAction; DWORD resultEffect; QWindowsDrag::m_canceled = false; QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this); windowDropSource->createCursors(); QWindowsDropDataObject *dropDataObject = new QWindowsDropDataObject(dropData); const Qt::DropActions possibleActions = drag->supportedActions(); const DWORD allowedEffects = translateToWinDragEffects(possibleActions); qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x" << hex << int(possibleActions) << "effects=0x" << allowedEffects << dec; const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect); const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect(); if (r == DRAGDROP_S_DROP) { if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) { dragResult = Qt::TargetMoveAction; resultEffect = DROPEFFECT_MOVE; } else { dragResult = translateToQDragDropAction(resultEffect); } // Force it to be a copy if an unsupported operation occurred. // This indicates a bug in the drop target. if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects)) { qWarning("%s: Forcing Qt::CopyAction", __FUNCTION__); dragResult = Qt::CopyAction; } } // clean up dropDataObject->releaseQt(); dropDataObject->Release(); // Will delete obj if refcount becomes 0 windowDropSource->Release(); // Will delete src if refcount becomes 0 qCDebug(lcQpaMime) << '<' << __FUNCTION__ << hex << "allowedEffects=0x" << allowedEffects << "reportedPerformedEffect=0x" << reportedPerformedEffect << " resultEffect=0x" << resultEffect << "hr=0x" << int(r) << dec << "dropAction=" << dragResult; return dragResult; }
STDMETHODIMP QOleDropTarget::DragOver( DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { #ifdef DEBUG_QDND_TGT qDebug( "QOleDropTarget::DragOver( %d, %d/%d, %d )", grfKeyState, pt.x, pt.y, *pdwEffect ); qDebug( "widget: %p, winID: %08x", widget, widget ? widget->winId() : 0 ); #endif if ( !qt_tryModalHelper( widget ) ) { *pdwEffect = DROPEFFECT_NONE; return NOERROR; } QPoint tmpPoint = widget->mapFromGlobal( QPoint( pt.x, pt.y ) ); // see if we should compress this event if ( ( tmpPoint == lastPoint || answerRect.contains( tmpPoint ) ) && lastKeyState == grfKeyState ) { *pdwEffect = choosenEffect; return NOERROR; } lastPoint = tmpPoint; lastKeyState = grfKeyState; QDragMoveEvent e( lastPoint ); e.setAction( translateKeyStateToQDropAction( grfKeyState, *pdwEffect ) ); e.accept(); QApplication::sendEvent( widget, &e ); answerRect = e.answerRect(); if ( e.isAccepted() ) choosenEffect = translateToWinDragEffects( e.action() ); else choosenEffect = DROPEFFECT_NONE; *pdwEffect = choosenEffect; return NOERROR; }
STDMETHODIMP QOleDropTarget::DragEnter( LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { #ifdef DEBUG_QDND_TGT qDebug( "QOleDropTarget::DragEnter( %p, %d, %d/%d, %d )", pIDataSource, grfKeyState, pt.x, pt.y, *pdwEffect ); qDebug( "widget: %p, winID: %08x", widget, widget ? widget->winId() : 0 ); #endif if ( !qt_tryModalHelper( widget ) ) { *pdwEffect = DROPEFFECT_NONE; return NOERROR; } pIDataObject = pIDataSource; pIDataObject->AddRef(); lastPoint = widget->mapFromGlobal( QPoint( pt.x, pt.y ) ); lastKeyState = grfKeyState; QDragEnterEvent e( lastPoint ); e.setAction( translateKeyStateToQDropAction( grfKeyState, *pdwEffect ) ); e.accept(); QApplication::sendEvent( widget, &e ); QDragResponseEvent re ( e.isAccepted() ); QApplication::sendEvent( widget, &re ); answerRect = e.answerRect(); if ( e.isAccepted() ) choosenEffect = translateToWinDragEffects( e.action() ); else choosenEffect = DROPEFFECT_NONE; *pdwEffect = choosenEffect; return NOERROR; }