virtual ~wxIDropTarget();
// accessors for wxDropTarget
+ HWND GetHWND() const { return m_hwnd; }
void SetHwnd(HWND hwnd) { m_hwnd = hwnd; }
// IDropTarget methods
}
#endif // 0
- if ( !m_pTarget->MSWIsAcceptedData(pIDataSource) ) {
- // we don't accept this kind of data
- *pdwEffect = DROPEFFECT_NONE;
-
- return S_OK;
- }
-
// for use in OnEnter and OnDrag calls
m_pTarget->MSWSetDataSource(pIDataSource);
m_pIDataObject = pIDataSource;
m_pIDataObject->AddRef();
- // we need client coordinates to pass to wxWin functions
- if ( !ScreenToClient(m_hwnd, (POINT *)&pt) )
+ if ( !m_pTarget->MSWIsAcceptedData(pIDataSource) ) {
+ // we don't accept this kind of data
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+ else
{
- wxLogLastError(wxT("ScreenToClient"));
+ // we need client coordinates to pass to wxWin functions
+ if ( !ScreenToClient(m_hwnd, (POINT *)&pt) )
+ {
+ wxLogLastError(wxT("ScreenToClient"));
+ }
+
+ // give some visual feedback
+ *pdwEffect = ConvertDragResultToEffect(
+ m_pTarget->OnEnter(pt.x, pt.y, ConvertDragEffectToResult(
+ GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction(), *pdwEffect))
+ )
+ );
}
- // give some visual feedback
- *pdwEffect = ConvertDragResultToEffect(
- m_pTarget->OnEnter(pt.x, pt.y, ConvertDragEffectToResult(
- GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction(), *pdwEffect))
- )
- );
+ // update drag image
+ const wxDragResult res = ConvertDragEffectToResult(*pdwEffect);
+ m_pTarget->MSWUpdateDragImageOnEnter(pt.x, pt.y, res);
+ m_pTarget->MSWUpdateDragImageOnDragOver(pt.x, pt.y, res);
return S_OK;
}
+
+
// Name : wxIDropTarget::DragOver
// Purpose : Indicates that the mouse was moved inside the window represented
// by this drop target.
*pdwEffect = DROPEFFECT_NONE;
}
+ // update drag image
+ m_pTarget->MSWUpdateDragImageOnDragOver(pt.x, pt.y,
+ ConvertDragEffectToResult(*pdwEffect));
+
return S_OK;
}
// release the held object
RELEASE_AND_NULL(m_pIDataObject);
+ // update drag image
+ m_pTarget->MSWUpdateDragImageOnLeave();
+
return S_OK;
}
// release the held object
RELEASE_AND_NULL(m_pIDataObject);
+ // update drag image
+ m_pTarget->MSWUpdateDragImageOnData(pt.x, pt.y,
+ ConvertDragEffectToResult(*pdwEffect));
+
return S_OK;
}
// ----------------------------------------------------------------------------
wxDropTarget::wxDropTarget(wxDataObject *dataObj)
- : wxDropTargetBase(dataObj)
+ : wxDropTargetBase(dataObj),
+ m_dropTargetHelper(NULL)
{
// create an IDropTarget implementation which will notify us about d&d
// operations.
// we will need the window handle for coords transformation later
m_pIDropTarget->SetHwnd((HWND)hwnd);
+ MSWInitDragImageSupport();
+
return true;
#endif
}
::CoLockObjectExternal(m_pIDropTarget, FALSE, TRUE);
#endif
+ MSWEndDragImageSupport();
+
+ // remove window reference
m_pIDropTarget->SetHwnd(0);
#endif
}
{
wxDataFormat format = MSWGetSupportedFormat(m_pIDataSource);
if ( format == wxDF_INVALID ) {
- // this is strange because IsAcceptedData() succeeded previously!
- wxFAIL_MSG(wxT("strange - did supported formats list change?"));
-
return false;
}
return n < nFormats ? format : wxFormatInvalid;
}
+// ----------------------------------------------------------------------------
+// drag image functions
+// ----------------------------------------------------------------------------
+
+void
+wxDropTarget::MSWEndDragImageSupport()
+{
+ // release drop target helper
+ if ( m_dropTargetHelper != NULL )
+ {
+ m_dropTargetHelper->Release();
+ m_dropTargetHelper = NULL;
+ }
+}
+
+void
+wxDropTarget::MSWInitDragImageSupport()
+{
+ // Use the default drop target helper to show shell drag images
+ CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER,
+ IID_IDropTargetHelper, (LPVOID*)&m_dropTargetHelper);
+}
+
+void
+wxDropTarget::MSWUpdateDragImageOnData(wxCoord x,
+ wxCoord y,
+ wxDragResult dragResult)
+{
+ // call corresponding event on drop target helper
+ if ( m_dropTargetHelper != NULL )
+ {
+ POINT pt = {x, y};
+ DWORD dwEffect = ConvertDragResultToEffect(dragResult);
+ m_dropTargetHelper->Drop(m_pIDataSource, &pt, dwEffect);
+ }
+}
+
+void
+wxDropTarget::MSWUpdateDragImageOnDragOver(wxCoord x,
+ wxCoord y,
+ wxDragResult dragResult)
+{
+ // call corresponding event on drop target helper
+ if ( m_dropTargetHelper != NULL )
+ {
+ POINT pt = {x, y};
+ DWORD dwEffect = ConvertDragResultToEffect(dragResult);
+ m_dropTargetHelper->DragOver(&pt, dwEffect);
+ }
+}
+
+void
+wxDropTarget::MSWUpdateDragImageOnEnter(wxCoord x,
+ wxCoord y,
+ wxDragResult dragResult)
+{
+ // call corresponding event on drop target helper
+ if ( m_dropTargetHelper != NULL )
+ {
+ POINT pt = {x, y};
+ DWORD dwEffect = ConvertDragResultToEffect(dragResult);
+ m_dropTargetHelper->DragEnter(m_pIDropTarget->GetHWND(), m_pIDataSource, &pt, dwEffect);
+ }
+}
+
+void
+wxDropTarget::MSWUpdateDragImageOnLeave()
+{
+ // call corresponding event on drop target helper
+ if ( m_dropTargetHelper != NULL )
+ {
+ m_dropTargetHelper->DragLeave();
+ }
+}
+
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------