4#include <QtCore/qt_windows.h>
8#if QT_CONFIG(clipboard)
9# include "qwindowsclipboard.h"
18#include <QtGui/qevent.h>
19#include <QtGui/qpixmap.h>
20#include <QtGui/qpainter.h>
21#include <QtGui/qrasterwindow.h>
22#include <QtGui/qguiapplication.h>
23#include <qpa/qwindowsysteminterface_p.h>
24#include <QtGui/private/qdnd_p.h>
25#include <QtGui/private/qguiapplication_p.h>
26#include <QtGui/private/qhighdpiscaling_p.h>
28#include <QtCore/qdebug.h>
29#include <QtCore/qbuffer.h>
30#include <QtCore/qpoint.h>
31#include <QtCore/qpointer.h>
32#include <QtCore/private/qcomobject_p.h>
39
40
41
42
43
44
56 QPainter painter(
this);
57 painter.drawPixmap(0, 0, m_pixmap);
67 QSurfaceFormat windowFormat = format();
68 windowFormat.setAlphaBufferSize(8);
69 setFormat(windowFormat);
70 setObjectName(QStringLiteral(
"QWindowsDragCursorWindow"));
71 setFlags(Qt::Popup | Qt::NoDropShadowWindowHint
72 | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
73 | Qt::WindowDoesNotAcceptFocus | Qt::WindowTransparentForInput);
78 if (p.cacheKey() == m_pixmap.cacheKey())
80 const QSize oldSize = m_pixmap.size();
81 QSize newSize = p.size();
82 qCDebug(lcQpaMime) <<
__FUNCTION__ << p.cacheKey() << newSize;
84 if (oldSize != newSize) {
85 const qreal pixDevicePixelRatio = p.devicePixelRatio();
86 if (pixDevicePixelRatio > 1.0 && qFuzzyCompare(pixDevicePixelRatio, devicePixelRatio()))
87 newSize /= qRound(pixDevicePixelRatio);
95
96
97
98
99
100
101
102
103
112 Qt::DropActions actions = Qt::IgnoreAction;
113 if (pdwEffects & DROPEFFECT_LINK)
114 actions |= Qt::LinkAction;
115 if (pdwEffects & DROPEFFECT_COPY)
116 actions |= Qt::CopyAction;
117 if (pdwEffects & DROPEFFECT_MOVE)
118 actions |= Qt::MoveAction;
124 if (pdwEffect & DROPEFFECT_LINK)
125 return Qt::LinkAction;
126 if (pdwEffect & DROPEFFECT_COPY)
127 return Qt::CopyAction;
128 if (pdwEffect & DROPEFFECT_MOVE)
129 return Qt::MoveAction;
130 return Qt::IgnoreAction;
135 DWORD effect = DROPEFFECT_NONE;
136 if (action & Qt::LinkAction)
137 effect |= DROPEFFECT_LINK;
138 if (action & Qt::CopyAction)
139 effect |= DROPEFFECT_COPY;
140 if (action & Qt::MoveAction)
141 effect |= DROPEFFECT_MOVE;
147 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
149 if (keyState & MK_SHIFT)
150 modifiers |= Qt::ShiftModifier;
151 if (keyState & MK_CONTROL)
152 modifiers |= Qt::ControlModifier;
153 if (keyState & MK_ALT)
154 modifiers |= Qt::AltModifier;
163
164
165
166
167
168
169
170
191 CursorEntry() : cacheKey(0) {}
192 CursorEntry(
const QPixmap &p, qint64 cK,
const CursorHandlePtr &c,
const QPoint &h) :
193 pixmap(p), cacheKey(cK), cursor(c), hotSpot(h) {}
197 CursorHandlePtr cursor;
201 typedef QMap<Qt::DropAction, CursorEntry> ActionCursorMap;
205 QPointer<QWindow> m_windowUnderMouse;
206 Qt::MouseButtons m_currentButtons;
207 ActionCursorMap m_cursors;
210#ifndef QT_NO_DEBUG_STREAM
220 , m_touchDragWindow(
nullptr)
222 qCDebug(lcQpaMime) <<
__FUNCTION__ << m_mode;
228 delete m_touchDragWindow;
229 qCDebug(lcQpaMime) <<
__FUNCTION__;
232#ifndef QT_NO_DEBUG_STREAM
235 d <<
"CursorEntry:" << e.pixmap.size() <<
'#' << e.cacheKey
236 <<
"HCURSOR" << e.cursor->handle() <<
"hotspot:" << e.hotSpot;
242
243
247 const QDrag *drag = m_drag->currentDrag();
248 const QPixmap pixmap = drag->pixmap();
249 const bool hasPixmap = !pixmap.isNull();
253 if (!platformScreen) {
254 if (
const QScreen *primaryScreen = QGuiApplication::primaryScreen())
255 platformScreen = primaryScreen->handle();
257 QPlatformCursor *platformCursor =
nullptr;
259 platformCursor = platformScreen->cursor();
261 if (GetSystemMetrics (SM_REMOTESESSION) != 0) {
263
264
265 const int rdpLargeCursor = qRound(qreal(96) / QHighDpiScaling::factor(platformScreen));
266 if (pixmap.width() > rdpLargeCursor || pixmap.height() > rdpLargeCursor)
270 qreal pixmapScaleFactor = 1;
271 qreal hotSpotScaleFactor = 1;
273 hotSpotScaleFactor = QHighDpiScaling::factor(platformScreen);
274 pixmapScaleFactor = hotSpotScaleFactor / pixmap.devicePixelRatio();
276 QPixmap scaledPixmap = (!hasPixmap || qFuzzyCompare(pixmapScaleFactor, 1.0))
278 : pixmap.scaled((QSizeF(pixmap.size()) * pixmapScaleFactor).toSize(),
279 Qt::KeepAspectRatio, Qt::SmoothTransformation);
280 scaledPixmap.setDevicePixelRatio(1);
282 Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
283 int actionCount =
int(
sizeof(actions) /
sizeof(actions[0]));
286 const QPoint hotSpot = qFuzzyCompare(hotSpotScaleFactor, 1.0)
288 : (QPointF(drag->hotSpot()) * hotSpotScaleFactor).toPoint();
289 for (
int cnum = 0; cnum < actionCount; ++cnum) {
290 const Qt::DropAction action = actions[cnum];
291 QPixmap cursorPixmap = drag->dragCursor(action);
292 if (cursorPixmap.isNull() && platformCursor)
293 cursorPixmap =
static_cast<
QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
294 const qint64 cacheKey = cursorPixmap.cacheKey();
295 const auto it = m_cursors.find(action);
296 if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
298 if (cursorPixmap.isNull()) {
299 qWarning(
"%s: Unable to obtain drag cursor for %d.",
__FUNCTION__, action);
304 QPixmap newPixmap = cursorPixmap;
307 const int x1 = qMin(-hotSpot.x(), 0);
308 const int x2 = qMax(scaledPixmap.width() - hotSpot.x(), cursorPixmap.width());
309 const int y1 = qMin(-hotSpot.y(), 0);
310 const int y2 = qMax(scaledPixmap.height() - hotSpot.y(), cursorPixmap.height());
311 QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
312 newCursor.fill(Qt::transparent);
313 QPainter p(&newCursor);
314 const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
315 p.drawPixmap(pmDest, scaledPixmap);
316 p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
317 newPixmap = newCursor;
318 newHotSpot =
QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
321 if (
const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newPixmap, newHotSpot)) {
322 const CursorEntry entry(newPixmap, cacheKey, CursorHandlePtr(
new CursorHandle(sysCursor)), newHotSpot);
323 if (it == m_cursors.end())
324 m_cursors.insert(action, entry);
329#ifndef QT_NO_DEBUG_OUTPUT
330 if (lcQpaMime().isDebugEnabled())
331 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
"pixmap" << pixmap.size() << m_cursors.size() <<
"cursors:\n" << m_cursors;
336
337
339QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
340QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
noexcept
345 Qt::MouseButtons buttons = QWindowsPointerHandler::queryMouseButtons();
348 if (fEscapePressed || QWindowsDrag::isCanceled()) {
349 result = DRAGDROP_S_CANCEL;
350 buttons = Qt::NoButton;
352 if (buttons && !m_currentButtons) {
353 m_currentButtons = buttons;
354 }
else if (m_currentButtons != buttons) {
355 result = DRAGDROP_S_DROP;
360 case DRAGDROP_S_DROP:
361 case DRAGDROP_S_CANCEL:
362 if (!m_windowUnderMouse.isNull() && m_mode != TouchDrag && fEscapePressed == FALSE
363 && buttons != lastButtons) {
366 const QPoint globalPos = QWindowsCursor::mousePosition();
367 const QPoint localPos = m_windowUnderMouse->handle()->mapFromGlobal(globalPos);
368 QWindowSystemInterface::handleMouseEvent(m_windowUnderMouse.data(),
369 QPointF(localPos), QPointF(globalPos),
370 QWindowsPointerHandler::queryMouseButtons(),
371 Qt::LeftButton, QEvent::MouseButtonRelease);
373 m_currentButtons = Qt::NoButton;
377 QGuiApplication::processEvents();
381 if (QWindowsContext::verbose > 1 || result != S_OK) {
382 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
"fEscapePressed=" << fEscapePressed
383 <<
"grfKeyState=" << grfKeyState <<
"buttons" << m_currentButtons
384 <<
"returns 0x" << Qt::hex <<
int(result) << Qt::dec;
386 return ResultFromScode(result);
390
391
393QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
394QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
noexcept
396 const Qt::DropAction action = translateToQDragDropAction(dwEffect);
397 m_drag->updateAction(action);
399 const qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey();
400 auto it = m_cursors.constFind(action);
402 if (it == m_cursors.constEnd() || (currentCacheKey && currentCacheKey != it.value().cacheKey)) {
404 it = m_cursors.constFind(action);
407 if (it != m_cursors.constEnd()) {
408 const CursorEntry &e = it.value();
411 SetCursor(e.cursor->handle());
415 if (QWindowsCursor::cursorState() != QWindowsCursor::State::Suppressed)
417 if (!m_touchDragWindow)
418 m_touchDragWindow =
new QWindowsDragCursorWindow;
419 m_touchDragWindow->setPixmap(e.pixmap);
420 m_touchDragWindow->setFramePosition(QCursor::pos() - e.hotSpot);
421 if (!m_touchDragWindow->isVisible())
422 m_touchDragWindow->show();
425 return ResultFromScode(S_OK);
428 return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
432
433
434
435
436
437
438
439
440
441
445 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
this << w;
450 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
this;
454 const QPoint &point, LPDWORD pdwEffect)
458 m_lastKeyState = grfKeyState;
461 const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
463 lastModifiers = toQtKeyboardModifiers(grfKeyState);
464 lastButtons = QWindowsPointerHandler::queryMouseButtons();
466 const QPlatformDragQtResponse response =
467 QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(),
468 m_lastPoint, actions,
469 lastButtons, lastModifiers);
471 m_answerRect = response.answerRect();
472 const Qt::DropAction action = response.acceptedAction();
473 if (response.isAccepted()) {
474 m_chosenEffect = translateToWinDragEffects(action);
476 m_chosenEffect = DROPEFFECT_NONE;
478 *pdwEffect = m_chosenEffect;
479 qCDebug(lcQpaMime) <<
__FUNCTION__ << m_window
480 << windowsDrag->dropData() <<
" supported actions=" << actions
481 <<
" mods=" << lastModifiers <<
" mouse=" << lastButtons
482 <<
" accepted: " << response.isAccepted() << action
483 << m_answerRect <<
" effect" << *pdwEffect;
486QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
487QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
488 POINTL pt, LPDWORD pdwEffect)
noexcept
490 if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
491 dh->DragEnter(
reinterpret_cast<HWND>(m_window->winId()), pDataObj,
reinterpret_cast<POINT*>(&pt), *pdwEffect);
493 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
"widget=" << m_window <<
" key=" << grfKeyState
494 <<
"pt=" << pt.x << pt.y;
496 QWindowsDrag::instance()->setDropDataObject(pDataObj);
498 const QPoint point = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y));
499 handleDrag(m_window, grfKeyState, point, pdwEffect);
503QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
504QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
noexcept
506 if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
507 dh->DragOver(
reinterpret_cast<POINT*>(&pt), *pdwEffect);
509 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
"m_window" << m_window <<
"key=" << grfKeyState
510 <<
"pt=" << pt.x << pt.y;
511 const QPoint tmpPoint = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y));
513 if ((tmpPoint == m_lastPoint || m_answerRect.contains(tmpPoint))
514 && m_lastKeyState == grfKeyState) {
515 *pdwEffect = m_chosenEffect;
516 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
"compressed event";
520 handleDrag(m_window, grfKeyState, tmpPoint, pdwEffect);
524QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
525QWindowsOleDropTarget::DragLeave()
noexcept
527 if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
530 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
' ' << m_window;
532 const auto *keyMapper = QWindowsContext::instance()->keyMapper();
533 lastModifiers = keyMapper->queryKeyboardModifiers();
534 lastButtons = QWindowsPointerHandler::queryMouseButtons();
536 QWindowSystemInterface::handleDrag(m_window,
nullptr, QPoint(), Qt::IgnoreAction,
537 Qt::NoButton, Qt::NoModifier);
539 if (!QDragManager::self()->source())
541 QWindowsDrag::instance()->releaseDropDataObject();
546#define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)
548QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
549QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
550 POINTL pt, LPDWORD pdwEffect)
noexcept
552 if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
553 dh->Drop(pDataObj,
reinterpret_cast<POINT*>(&pt), *pdwEffect);
555 qCDebug(lcQpaMime) <<
__FUNCTION__ <<
' ' << m_window
556 <<
"keys=" << grfKeyState <<
"pt=" << pt.x <<
',' << pt.y;
558 m_lastPoint = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y));
560 QWindowsDrag *windowsDrag = QWindowsDrag::instance();
562 lastModifiers = toQtKeyboardModifiers(grfKeyState);
563 lastButtons = QWindowsPointerHandler::queryMouseButtons();
565 const QPlatformDropQtResponse response =
566 QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(),
568 translateToQDragDropActions(*pdwEffect),
572 m_lastKeyState = grfKeyState;
574 if (response.isAccepted()) {
575 const Qt::DropAction action = response.acceptedAction();
576 if (action == Qt::MoveAction || action == Qt::TargetMoveAction) {
577 if (action == Qt::MoveAction)
578 m_chosenEffect = DROPEFFECT_MOVE;
580 m_chosenEffect = DROPEFFECT_COPY;
581 HGLOBAL hData = GlobalAlloc(0,
sizeof(DWORD));
583 auto *moveEffect =
reinterpret_cast<DWORD *>(GlobalLock(hData));
584 *moveEffect = DROPEFFECT_MOVE;
587 memset(&medium, 0,
sizeof(STGMEDIUM));
588 medium.tymed = TYMED_HGLOBAL;
589 medium.hGlobal = hData;
591 format.cfFormat = CLIPFORMAT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT));
592 format.tymed = TYMED_HGLOBAL;
593 format.ptd =
nullptr;
596 windowsDrag->dropDataObject()->SetData(&format, &medium,
true);
599 m_chosenEffect = translateToWinDragEffects(action);
602 m_chosenEffect = DROPEFFECT_NONE;
604 *pdwEffect = m_chosenEffect;
606 windowsDrag->releaseDropDataObject();
612
613
614
615
623 if (m_cachedDropTargetHelper)
624 m_cachedDropTargetHelper->Release();
628
629
633 if (
const QDrag *drag = currentDrag())
634 return drag->mimeData();
639
640
642 if (!m_cachedDropTargetHelper) {
643 CoCreateInstance(CLSID_DragDropHelper,
nullptr, CLSCTX_INPROC_SERVER,
644 IID_IDropTargetHelper,
645 reinterpret_cast<
void**>(&m_cachedDropTargetHelper));
647 return m_cachedDropTargetHelper;
656 const HWND hwnd = hasMouseCapture ?
reinterpret_cast<HWND>(underMouse->winId()) : ::GetFocus();
657 bool starting =
false;
661 if (::GetMessage(&msg, hwnd, 0, 0) > 0) {
663 if (msg.message == WM_MOUSEMOVE) {
666 if (!starting && (msg.wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) == 0)
669 return ::DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect);
674 const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
676 POINTER_INFO pointerInfo{};
677 if (!GetPointerInfo(pointerId, &pointerInfo))
680 if (pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) {
682 DWORD flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;
683 if (IS_POINTER_FIRSTBUTTON_WPARAM(msg.wParam))
684 flags |= MOUSEEVENTF_LEFTDOWN;
685 if (IS_POINTER_SECONDBUTTON_WPARAM(msg.wParam))
686 flags |= MOUSEEVENTF_RIGHTDOWN;
687 if (IS_POINTER_THIRDBUTTON_WPARAM(msg.wParam))
688 flags |= MOUSEEVENTF_MIDDLEDOWN;
692 if (::GetCursorPos(&pt)) {
695 if ((flags & MOUSEEVENTF_LEFTDOWN || flags & MOUSEEVENTF_RIGHTDOWN || flags & MOUSEEVENTF_MIDDLEDOWN)
696 && (pt.x != pointerInfo.ptPixelLocation.x || pt.y != pointerInfo.ptPixelLocation.y)) {
698 const int origin_x = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
699 const int origin_y = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
700 const int virt_w = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
701 const int virt_h = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
702 const int virt_x = pointerInfo.ptPixelLocation.x - origin_x;
703 const int virt_y = pointerInfo.ptPixelLocation.y - origin_y;
706 input.type = INPUT_MOUSE;
707 input.mi.dx =
static_cast<DWORD>(virt_x * (65535.0 / virt_w));
708 input.mi.dy =
static_cast<DWORD>(virt_y * (65535.0 / virt_h));
709 input.mi.dwFlags = flags;
711 ::SendInput(1, &input,
sizeof(input));
719 qWindowsWndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
733 QMimeData *dropData = drag->mimeData();
734 Qt::DropAction dragResult = Qt::IgnoreAction;
741 const Qt::DropActions possibleActions = drag->supportedActions();
742 const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
743 qCDebug(lcQpaMime) <<
'>' <<
__FUNCTION__ <<
"possible Actions=0x"
744 << Qt::hex <<
int(possibleActions) <<
"effects=0x" << allowedEffects << Qt::dec;
745 const HRESULT r = startDoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
746 const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
747 if (r == DRAGDROP_S_DROP) {
748 if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) {
749 dragResult = Qt::TargetMoveAction;
750 resultEffect = DROPEFFECT_MOVE;
752 dragResult = translateToQDragDropAction(resultEffect);
756 if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects)) {
757 qWarning(
"%s: Forcing Qt::CopyAction",
__FUNCTION__);
758 dragResult = Qt::CopyAction;
762 dropDataObject->releaseQt();
763 dropDataObject->Release();
764 windowDropSource->Release();
765 qCDebug(lcQpaMime) <<
'<' <<
__FUNCTION__ << Qt::hex <<
"allowedEffects=0x" << allowedEffects
766 <<
"reportedPerformedEffect=0x" << reportedPerformedEffect
767 <<
" resultEffect=0x" << resultEffect <<
"hr=0x" <<
int(r) << Qt::dec <<
"dropAction=" << dragResult;
778 qCDebug(lcQpaMime) <<
__FUNCTION__ << m_dropDataObject;
779 if (m_dropDataObject) {
780 m_dropDataObject->Release();
781 m_dropDataObject =
nullptr;
\inmodule QtCore\reentrant
Singleton container for all relevant information.
QWindowsScreenManager & screenManager()
static QWindowsContext * instance()
Platform cursor implementation.
static QPoint mousePosition()
static State cursorState()
A toplevel window showing the drag icon in case of touch drag.
void setPixmap(const QPixmap &p)
void paintEvent(QPaintEvent *) override
Handles paint events passed in the event parameter.
QWindowsDragCursorWindow(QWindow *parent=nullptr)
Windows drag implementation.
QMimeData * dropData()
Return data for a drop in process.
static QWindowsDrag * instance()
void releaseDropDataObject()
IDropTargetHelper * dropHelper()
May be used to handle extended cursors functionality for drags from outside the app.
Qt::DropAction drag(QDrag *drag) override
QWindowsOleDataObject subclass specialized for handling Drag&Drop.
QWindowsDropDataObject(QMimeData *mimeData)
Special mime data class for data retrieval from Drag operations.
IDataObject * retrieveDataObject() const override
static QWindowsIntegration * instance()
Implementation of IDropSource.
STDMETHOD GiveFeedback(DWORD dwEffect) noexcept override
Give feedback: Change cursor according to action.
~QWindowsOleDropSource() override
void createCursors()
Blend custom pixmap with cursors.
QWindowsOleDropSource(QWindowsDrag *drag)
STDMETHOD QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) noexcept override
Check for cancel.
Implementation of IDropTarget.
~QWindowsOleDropTarget() override
const QWindowsScreen * screenAtDp(const QPoint &p) const
bool hasMouseCapture() const
static HRESULT startDoDragDrop(LPDATAOBJECT pDataObj, LPDROPSOURCE pDropSource, DWORD dwOKEffects, LPDWORD pdwEffect)
static Qt::DropActions translateToQDragDropActions(DWORD pdwEffects)
static Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
static Qt::MouseButtons lastButtons
static Qt::DropAction translateToQDragDropAction(DWORD pdwEffect)
static DWORD translateToWinDragEffects(Qt::DropActions action)
static Qt::KeyboardModifiers lastModifiers