1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (info@qt.nokia.com)
7 ** This file is part of the plugins of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qwindowsdrag.h"
43 #include "qwindowscontext.h"
44 #include "qwindowsclipboard.h"
45 #include "qwindowsintegration.h"
46 #include "qwindowsole.h"
47 #include "qtwindows_additional.h"
48 #include "qwindowswindow.h"
49 #include "qwindowsmousehandler.h"
50 #include "qwindowscursor.h"
52 #include <QtGui/QMouseEvent>
53 #include <QtGui/QPixmap>
54 #include <QtGui/QPainter>
55 #include <QtGui/QGuiApplication>
57 #include <QtCore/QDebug>
58 #include <QtCore/QPoint>
65 \class QWindowsDropMimeData
66 \brief Special mime data class for data retrieval from Drag operations.
68 Implementation of QWindowsInternalMimeDataBase which retrieves the
69 current drop data object from QWindowsDrag.
72 \ingroup qt-lighthouse-win
75 IDataObject *QWindowsDropMimeData::retrieveDataObject() const
77 return QWindowsDrag::instance()->dropDataObject();
80 static inline Qt::DropActions translateToQDragDropActions(DWORD pdwEffects)
82 Qt::DropActions actions = Qt::IgnoreAction;
83 if (pdwEffects & DROPEFFECT_LINK)
84 actions |= Qt::LinkAction;
85 if (pdwEffects & DROPEFFECT_COPY)
86 actions |= Qt::CopyAction;
87 if (pdwEffects & DROPEFFECT_MOVE)
88 actions |= Qt::MoveAction;
92 static inline Qt::DropAction translateToQDragDropAction(DWORD pdwEffect)
94 if (pdwEffect & DROPEFFECT_LINK)
95 return Qt::LinkAction;
96 if (pdwEffect & DROPEFFECT_COPY)
97 return Qt::CopyAction;
98 if (pdwEffect & DROPEFFECT_MOVE)
99 return Qt::MoveAction;
100 return Qt::IgnoreAction;
103 static inline DWORD translateToWinDragEffects(Qt::DropActions action)
105 DWORD effect = DROPEFFECT_NONE;
106 if (action & Qt::LinkAction)
107 effect |= DROPEFFECT_LINK;
108 if (action & Qt::CopyAction)
109 effect |= DROPEFFECT_COPY;
110 if (action & Qt::MoveAction)
111 effect |= DROPEFFECT_MOVE;
115 static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
117 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
119 if (keyState & MK_SHIFT)
120 modifiers |= Qt::ShiftModifier;
121 if (keyState & MK_CONTROL)
122 modifiers |= Qt::ControlModifier;
123 if (keyState & MK_ALT)
124 modifiers |= Qt::AltModifier;
130 \class QWindowsOleDropSource
131 \brief Implementation of IDropSource
133 Used for drag operations.
136 \ingroup qt-lighthouse-win
139 class QWindowsOleDropSource : public IDropSource
142 QWindowsOleDropSource();
143 virtual ~QWindowsOleDropSource();
145 void createCursors();
148 STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj);
149 STDMETHOD_(ULONG,AddRef)(void);
150 STDMETHOD_(ULONG,Release)(void);
152 // IDropSource methods
153 STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState);
154 STDMETHOD(GiveFeedback)(DWORD dwEffect);
157 typedef QMap <Qt::DropAction, HCURSOR> ActionCursorMap;
159 inline void clearCursors();
161 Qt::MouseButtons m_currentButtons;
162 Qt::DropAction m_currentAction;
163 ActionCursorMap m_cursors;
168 QWindowsOleDropSource::QWindowsOleDropSource() :
169 m_currentButtons(Qt::NoButton), m_currentAction(Qt::IgnoreAction),
172 if (QWindowsContext::verboseOLE)
173 qDebug("%s", __FUNCTION__);
176 QWindowsOleDropSource::~QWindowsOleDropSource()
179 if (QWindowsContext::verboseOLE)
180 qDebug("%s", __FUNCTION__);
183 void QWindowsOleDropSource::createCursors()
185 QDragManager *manager = QDragManager::self();
186 if (!manager || !manager->object)
188 const QPixmap pixmap = manager->object->pixmap();
189 const bool hasPixmap = !pixmap.isNull();
190 if (!hasPixmap && manager->dragPrivate()->customCursors.isEmpty())
193 QList<Qt::DropAction> actions;
194 actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction;
196 actions << Qt::IgnoreAction;
197 const QPoint hotSpot = manager->object->hotSpot();
198 for (int cnum = 0; cnum < actions.size(); ++cnum) {
199 const QPixmap cpm = manager->dragCursor(actions.at(cnum));
201 int h = cpm.height();
204 const int x1 = qMin(-hotSpot.x(), 0);
205 const int x2 = qMax(pixmap.width() - hotSpot.x(), cpm.width());
206 const int y1 = qMin(-hotSpot.y(), 0);
207 const int y2 = qMax(pixmap.height() - hotSpot.y(), cpm.height());
213 const QRect srcRect = pixmap.rect();
214 const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
215 const QPoint newHotSpot = hotSpot;
216 QPixmap newCursor(w, h);
218 newCursor.fill(QColor(0, 0, 0, 0));
219 QPainter p(&newCursor);
220 p.drawPixmap(pmDest, pixmap, srcRect);
221 p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm);
226 const int hotX = hasPixmap ? qMax(0,newHotSpot.x()) : 0;
227 const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0;
229 if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY))
230 m_cursors.insert(actions.at(cnum), sysCursor);
232 if (QWindowsContext::verboseOLE)
233 qDebug("%s %d cursors", __FUNCTION__, m_cursors.size());
236 void QWindowsOleDropSource::clearCursors()
238 if (!m_cursors.isEmpty()) {
239 const ActionCursorMap::const_iterator cend = m_cursors.constEnd();
240 for (ActionCursorMap::const_iterator it = m_cursors.constBegin(); it != cend; ++it)
241 DestroyCursor(it.value());
246 //---------------------------------------------------------------------
248 //---------------------------------------------------------------------
251 QWindowsOleDropSource::QueryInterface(REFIID iid, void FAR* FAR* ppv)
253 if (iid == IID_IUnknown || iid == IID_IDropSource) {
259 return ResultFromScode(E_NOINTERFACE);
263 QWindowsOleDropSource::AddRef(void)
269 QWindowsOleDropSource::Release(void)
279 \brief Check for cancel.
282 QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
283 QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
287 if (fEscapePressed || QWindowsDrag::instance()->dragBeingCancelled()) {
288 hr = ResultFromScode(DRAGDROP_S_CANCEL);
292 // grfKeyState is broken on CE & some Windows XP versions,
293 // therefore we need to check the state manually
294 if ((GetAsyncKeyState(VK_LBUTTON) == 0)
295 && (GetAsyncKeyState(VK_MBUTTON) == 0)
296 && (GetAsyncKeyState(VK_RBUTTON) == 0)) {
297 hr = ResultFromScode(DRAGDROP_S_DROP);
301 const Qt::MouseButtons buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
302 if (m_currentButtons == Qt::NoButton) {
303 m_currentButtons = buttons;
305 // Button changed: Complete Drop operation.
306 if (!(m_currentButtons & buttons)) {
307 hr = ResultFromScode(DRAGDROP_S_DROP);
312 QGuiApplication::processEvents();
316 QDragManager::self()->willDrop = hr == DRAGDROP_S_DROP;
318 if (QWindowsContext::verboseOLE
319 && (QWindowsContext::verboseOLE > 1 || hr != S_OK))
320 qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d willDrop = %d returns 0x%x",
321 __FUNCTION__, fEscapePressed,grfKeyState, int(m_currentButtons),
322 QDragManager::self()->willDrop, int(hr));
327 \brief Give feedback: Change cursor accoding to action.
330 QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
331 QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
333 const Qt::DropAction action = translateToQDragDropAction(dwEffect);
335 if (QWindowsContext::verboseOLE > 2)
336 qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action);
338 if (m_currentAction != action) {
339 m_currentAction = action;
340 QDragManager::self()->emitActionChanged(m_currentAction);
343 const ActionCursorMap::const_iterator it = m_cursors.constFind(m_currentAction);
344 if (it != m_cursors.constEnd()) {
345 SetCursor(it.value());
346 return ResultFromScode(S_OK);
349 return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
353 \class QWindowsOleDropTarget
354 \brief Implementation of IDropTarget
356 To be registered for each window. Currently, drop sites
357 are enabled for top levels. The child window handling
358 (sending DragEnter/Leave, etc) is handled in here.
361 \ingroup qt-lighthouse-win
364 QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
365 m_refs(1), m_window(w), m_currentWindow(0), m_chosenEffect(0), m_lastKeyState(0)
367 if (QWindowsContext::verboseOLE)
368 qDebug() << __FUNCTION__ << this << w;
371 QWindowsOleDropTarget::~QWindowsOleDropTarget()
373 if (QWindowsContext::verboseOLE)
374 qDebug("%s %p", __FUNCTION__, this);
378 QWindowsOleDropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv)
380 if (iid == IID_IUnknown || iid == IID_IDropTarget) {
386 return ResultFromScode(E_NOINTERFACE);
390 QWindowsOleDropTarget::AddRef(void)
396 QWindowsOleDropTarget::Release(void)
405 QWindow *QWindowsOleDropTarget::findDragOverWindow(const POINTL &pt) const
407 if (QWindowsWindow *child =
408 QWindowsWindow::baseWindowOf(m_window)->childAtScreenPoint(QPoint(pt.x, pt.y)))
409 return child->window();
413 QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
414 QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
415 POINTL pt, LPDWORD pdwEffect)
417 if (QWindowsContext::verboseOLE)
418 qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y);
420 QWindowsDrag::instance()->setDropDataObject(pDataObj);
422 m_currentWindow = m_window;
423 sendDragEnterEvent(m_window, grfKeyState, pt, pdwEffect);
424 *pdwEffect = m_chosenEffect;
428 void QWindowsOleDropTarget::sendDragEnterEvent(QWindow *dragEnterWidget,
430 POINTL pt, LPDWORD pdwEffect)
432 Q_ASSERT(dragEnterWidget);
434 m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dragEnterWidget, QPoint(pt.x,pt.y));
435 m_lastKeyState = grfKeyState;
437 m_chosenEffect = DROPEFFECT_NONE;
439 QDragManager *manager = QDragManager::self();
440 QMimeData *md = manager->dropData();
441 const Qt::MouseButtons mouseButtons
442 = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
443 const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
444 const Qt::KeyboardModifiers keyMods = toQtKeyboardModifiers(grfKeyState);
445 QDragEnterEvent enterEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
446 QGuiApplication::sendEvent(m_currentWindow, &enterEvent);
447 m_answerRect = enterEvent.answerRect();
448 if (QWindowsContext::verboseOLE)
449 qDebug() << __FUNCTION__ << " sent drag enter to " << m_window
450 << *md << " actions=" << actions
451 << " mods=" << keyMods << " accepted: "
452 << enterEvent.isAccepted();
454 if (enterEvent.isAccepted())
455 m_chosenEffect = translateToWinDragEffects(enterEvent.dropAction());
456 // Documentation states that a drag move event is sent immediately after
457 // a drag enter event. This will honor widgets overriding dragMoveEvent only:
458 if (enterEvent.isAccepted()) {
459 QDragMoveEvent moveEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
460 m_answerRect = enterEvent.answerRect();
461 moveEvent.setDropAction(enterEvent.dropAction());
462 moveEvent.accept(); // accept by default, since enter event was accepted.
464 QGuiApplication::sendEvent(dragEnterWidget, &moveEvent);
465 if (moveEvent.isAccepted()) {
466 m_answerRect = moveEvent.answerRect();
467 m_chosenEffect = translateToWinDragEffects(moveEvent.dropAction());
469 m_chosenEffect = DROPEFFECT_NONE;
474 QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
475 QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
477 QWindow *dragOverWindow = findDragOverWindow(pt);
479 const QPoint tmpPoint = QWindowsGeometryHint::mapFromGlobal(dragOverWindow, QPoint(pt.x,pt.y));
480 // see if we should compress this event
481 if ((tmpPoint == m_lastPoint || m_answerRect.contains(tmpPoint))
482 && m_lastKeyState == grfKeyState) {
483 *pdwEffect = m_chosenEffect;
487 if (QWindowsContext::verboseOLE > 1)
488 qDebug().nospace() << '>' << __FUNCTION__ << ' ' << m_window << " current "
489 << dragOverWindow << " key=" << grfKeyState
490 << " pt=" <<pt.x << ',' << pt.y;
492 if (dragOverWindow != m_currentWindow) {
493 QPointer<QWindow> dragOverWindowGuard(dragOverWindow);
494 // Send drag leave event to the previous drag widget.
495 // Drag-Over widget might be deleted in DragLeave,
496 // (tasktracker 218353).
497 QDragLeaveEvent dragLeave;
499 QGuiApplication::sendEvent(m_currentWindow, &dragLeave);
500 if (!dragOverWindowGuard) {
501 dragOverWindow = findDragOverWindow(pt);
503 // Send drag enter event to the current drag widget.
504 m_currentWindow = dragOverWindow;
505 sendDragEnterEvent(dragOverWindow, grfKeyState, pt, pdwEffect);
508 QDragManager *manager = QDragManager::self();
509 QMimeData *md = manager->dropData();
511 const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
513 QDragMoveEvent oldEvent(m_lastPoint, actions, md,
514 QWindowsMouseHandler::keyStateToMouseButtons(m_lastKeyState),
515 toQtKeyboardModifiers(m_lastKeyState));
517 m_lastPoint = tmpPoint;
518 m_lastKeyState = grfKeyState;
520 QDragMoveEvent e(tmpPoint, actions, md,
521 QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
522 toQtKeyboardModifiers(grfKeyState));
523 if (m_chosenEffect != DROPEFFECT_NONE) {
524 if (oldEvent.dropAction() == e.dropAction() &&
525 oldEvent.keyboardModifiers() == e.keyboardModifiers())
526 e.setDropAction(translateToQDragDropAction(m_chosenEffect));
529 QGuiApplication::sendEvent(dragOverWindow, &e);
531 m_answerRect = e.answerRect();
533 m_chosenEffect = translateToWinDragEffects(e.dropAction());
535 m_chosenEffect = DROPEFFECT_NONE;
536 *pdwEffect = m_chosenEffect;
538 if (QWindowsContext::verboseOLE > 1)
539 qDebug("<%s effect=0x%lx", __FUNCTION__, m_chosenEffect);
543 QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
544 QWindowsOleDropTarget::DragLeave()
546 if (QWindowsContext::verboseOLE)
547 qDebug().nospace() <<__FUNCTION__ << ' ' << m_window;
551 QGuiApplication::sendEvent(m_window, &e);
552 QWindowsDrag::instance()->releaseDropDataObject();
557 #define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)
559 QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
560 QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState,
561 POINTL pt, LPDWORD pdwEffect)
563 QWindow *dropWindow = findDragOverWindow(pt);
565 if (QWindowsContext::verboseOLE)
566 qDebug().nospace() << __FUNCTION__ << ' ' << m_window
567 << " on " << dropWindow
568 << " keys=" << grfKeyState << " pt="
569 << pt.x << ',' << pt.y;
571 m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dropWindow, QPoint(pt.x,pt.y));
572 // grfKeyState does not all ways contain button state in the drop so if
573 // it doesn't then use the last known button state;
574 if ((grfKeyState & KEY_STATE_BUTTON_MASK) == 0)
575 grfKeyState |= m_lastKeyState & KEY_STATE_BUTTON_MASK;
576 m_lastKeyState = grfKeyState;
578 QWindowsDrag *windowsDrag = QWindowsDrag::instance();
579 QDragManager *manager = QDragManager::self();
580 QMimeData *md = manager->dropData();
581 QDropEvent e(m_lastPoint, translateToQDragDropActions(*pdwEffect), md,
582 QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
583 toQtKeyboardModifiers(grfKeyState));
584 if (m_chosenEffect != DROPEFFECT_NONE)
585 e.setDropAction(translateToQDragDropAction(m_chosenEffect));
587 QGuiApplication::sendEvent(dropWindow, &e);
588 if (m_chosenEffect != DROPEFFECT_NONE)
591 if (e.isAccepted()) {
592 if (e.dropAction() == Qt::MoveAction || e.dropAction() == Qt::TargetMoveAction) {
593 if (e.dropAction() == Qt::MoveAction)
594 m_chosenEffect = DROPEFFECT_MOVE;
596 m_chosenEffect = DROPEFFECT_COPY;
597 HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD));
599 DWORD *moveEffect = (DWORD *)GlobalLock(hData);;
600 *moveEffect = DROPEFFECT_MOVE;
603 memset(&medium, 0, sizeof(STGMEDIUM));
604 medium.tymed = TYMED_HGLOBAL;
605 medium.hGlobal = hData;
607 format.cfFormat = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);
608 format.tymed = TYMED_HGLOBAL;
612 windowsDrag->dropDataObject()->SetData(&format, &medium, true);
615 m_chosenEffect = translateToWinDragEffects(e.dropAction());
618 m_chosenEffect = DROPEFFECT_NONE;
620 *pdwEffect = m_chosenEffect;
622 windowsDrag->releaseDropDataObject();
628 \brief Windows drag implementation.
630 \ingroup qt-lighthouse-win
633 QWindowsDrag::QWindowsDrag() : m_dropDataObject(0), m_dragBeingCancelled(false)
637 QWindowsDrag::~QWindowsDrag()
641 void QWindowsDrag::startDrag()
643 // TODO: Accessibility handling?
644 QDragManager *dragManager = QDragManager::self();
645 QMimeData *dropData = dragManager->dropData();
646 m_dragBeingCancelled = false;
649 QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource();
650 windowDropSource->createCursors();
651 QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
652 const Qt::DropActions possibleActions = dragManager->possible_actions;
653 const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
654 if (QWindowsContext::verboseOLE)
655 qDebug(">%s possible Actions=%x, effects=0x%lx", __FUNCTION__,
656 int(possibleActions), allowedEffects);
657 const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
658 const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
659 Qt::DropAction ret = Qt::IgnoreAction;
660 if (r == DRAGDROP_S_DROP) {
661 if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) {
662 ret = Qt::TargetMoveAction;
663 resultEffect = DROPEFFECT_MOVE;
665 ret = translateToQDragDropAction(resultEffect);
667 // Force it to be a copy if an unsupported operation occurred.
668 // This indicates a bug in the drop target.
669 if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects))
670 ret = Qt::CopyAction;
672 dragManager->setCurrentTarget(0);
676 dropDataObject->releaseQt();
677 dropDataObject->Release(); // Will delete obj if refcount becomes 0
678 windowDropSource->Release(); // Will delete src if refcount becomes 0
679 if (QWindowsContext::verboseOLE)
680 qDebug("<%s allowedEffects=0x%lx, reportedPerformedEffect=0x%lx, resultEffect=0x%lx, hr=0x%x, dropAction=%d",
681 __FUNCTION__, allowedEffects, reportedPerformedEffect, resultEffect, int(r), ret);
684 void QWindowsDrag::move(const QMouseEvent *me)
686 const QPoint pos = me->pos();
687 if (QWindowsContext::verboseOLE)
688 qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
691 void QWindowsDrag::drop(const QMouseEvent *me)
693 const QPoint pos = me->pos();
694 if (QWindowsContext::verboseOLE)
695 qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
698 void QWindowsDrag::cancel()
700 // TODO: Accessibility handling?
701 if (QWindowsContext::verboseOLE)
702 qDebug("%s", __FUNCTION__);
703 m_dragBeingCancelled = true;
706 QWindowsDrag *QWindowsDrag::instance()
708 return static_cast<QWindowsDrag *>(QWindowsIntegration::instance()->drag());
711 void QWindowsDrag::releaseDropDataObject()
713 if (QWindowsContext::verboseOLE)
714 qDebug("%s %p", __FUNCTION__, m_dropDataObject);
715 if (m_dropDataObject) {
716 m_dropDataObject->Release();
717 m_dropDataObject = 0;