From 0f14ea3f3a05ef785b44fa610bf90ff3b5ba7beb Mon Sep 17 00:00:00 2001 From: Cyril Oblikov Date: Tue, 23 Oct 2012 18:00:58 +0300 Subject: [PATCH] New-style Windows cursors when dragging object from outside New-style drag&drop cursors are used now on Windows when user drags object to application from outside (e.g. image from Explorer). This is achieved by using IDropTargetHelper. Change-Id: I67e1db73cf433e235fce891eef0093cd4e605904 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsdrag.cpp | 35 ++++++++++++++++++++++++-- src/plugins/platforms/windows/qwindowsdrag.h | 6 +++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index f74b214..ad2ff22 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -595,6 +595,9 @@ QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->DragEnter(reinterpret_cast(m_window->winId()), pDataObj, reinterpret_cast(&pt), *pdwEffect); + if (QWindowsContext::verboseOLE) qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y); @@ -608,6 +611,9 @@ QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->DragOver(reinterpret_cast(&pt), *pdwEffect); + QWindow *dragOverWindow = findDragOverWindow(pt); if (QWindowsContext::verboseOLE) qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, dragOverWindow, grfKeyState, pt.x, pt.y); @@ -628,6 +634,9 @@ QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::DragLeave() { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->DragLeave(); + if (QWindowsContext::verboseOLE) qDebug().nospace() <<__FUNCTION__ << ' ' << m_window; @@ -640,9 +649,12 @@ QWindowsOleDropTarget::DragLeave() #define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, +QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->Drop(pDataObj, reinterpret_cast(&pt), *pdwEffect); + QWindow *dropWindow = findDragOverWindow(pt); if (QWindowsContext::verboseOLE) @@ -700,6 +712,10 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, return NOERROR; } +#if defined(Q_CC_MINGW) && !defined(_WIN32_IE) +# define _WIN32_IE 0x0501 +#endif + /*! \class QWindowsDrag \brief Windows drag implementation. @@ -707,12 +723,15 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, \ingroup qt-lighthouse-win */ -QWindowsDrag::QWindowsDrag() : m_dropDataObject(0) +QWindowsDrag::QWindowsDrag() : + m_dropDataObject(0), m_cachedDropTargetHelper(0) { } QWindowsDrag::~QWindowsDrag() { + if (m_cachedDropTargetHelper) + m_cachedDropTargetHelper->Release(); } /*! @@ -726,6 +745,18 @@ QMimeData *QWindowsDrag::dropData() return &m_dropData; } +/*! + \brief May be used to handle extended cursors functionality for drags from outside the app. +*/ +IDropTargetHelper* QWindowsDrag::dropHelper() { + if (!m_cachedDropTargetHelper) { + CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, + IID_IDropTargetHelper, + reinterpret_cast(&m_cachedDropTargetHelper)); + } + return m_cachedDropTargetHelper; +} + QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const { switch (action) { diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index ab06545..d3bfd36 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -47,6 +47,8 @@ #include #include +struct IDropTargetHelper; + QT_BEGIN_NAMESPACE class QWindowsDropMimeData : public QWindowsInternalMimeData { public: @@ -100,12 +102,16 @@ public: void releaseDropDataObject(); QMimeData *dropData(); + IDropTargetHelper* dropHelper(); + QPixmap defaultCursor(Qt::DropAction action) const; private: QWindowsDropMimeData m_dropData; IDataObject *m_dropDataObject; + IDropTargetHelper* m_cachedDropTargetHelper; + mutable QPixmap m_copyDragCursor; mutable QPixmap m_moveDragCursor; mutable QPixmap m_linkDragCursor; -- 2.7.4