+/////////////////////////////////////////////////////////////////////////////
+// Private functions
+/////////////////////////////////////////////////////////////////////////////
+
+#if 0
+static wxDragResult ConvertDragEffectToResult (
+ DWORD dwEffect
+)
+{
+ switch (dwEffect)
+ {
+ case DO_COPY:
+ return wxDragCopy;
+
+ case DO_LINK:
+ return wxDragLink;
+
+ case DO_MOVE:
+ return wxDragMove;
+
+ default:
+ case DO_DEFAULT:
+ return wxDragNone;
+ }
+} // end of ConvertDragEffectToResult
+
+static DWORD ConvertDragResultToEffect (
+ wxDragResult eResult
+)
+{
+ switch (eResult)
+ {
+ case wxDragCopy:
+ return DO_COPY;
+
+ case wxDragLink:
+ return DO_LINK;
+
+ case wxDragMove:
+ return DO_MOVE;
+
+ default:
+ case wxDragNone:
+ return DO_DEFAULT;
+ }
+} // end of ConvertDragResultToEffect
+#endif
+
+class CIDropTarget
+{
+public:
+ CIDropTarget(wxDropTarget* pTarget)
+ {
+ m_pTarget = pTarget;
+ m_pDragItem = NULL;
+ }
+ virtual ~CIDropTarget() { }
+
+ //
+ // Accessors for CDropTarget
+ //
+ void Free(void) { ::DrgFreeDraginfo(m_pDragInfo); }
+ PDRAGINFO GetDataSource(void) { return m_pDragInfo; }
+ void SetDataSource(PDRAGINFO pDragInfo) { m_pDragInfo = pDragInfo; }
+ void SetHWND(HWND hWnd) { m_hWnd = hWnd; }
+
+ //
+ // CIDropTarget methods
+ //
+ bool DragLeave(void);
+ MRESULT DragOver(void);
+ MRESULT Drop(void);
+
+protected:
+
+ PDRAGINFO m_pDragInfo;
+ PDRAGITEM m_pDragItem; // !NULL between DragEnter and DragLeave/Drop
+ wxDropTarget* m_pTarget; // the real target (we're just a proxy)
+ HWND m_hWnd; // window we're associated with
+}; // end of CLASS CIDropTarget
+
+bool CIDropTarget::DragLeave()
+{
+ //
+ // Remove the UI feedback
+ //
+ m_pTarget->OnLeave();
+
+ //
+ // Release the held object
+ //
+ Free();
+ return true;
+} // end of CIDropTarget::DragLeave
+
+MRESULT CIDropTarget::DragOver ()
+{
+ char zBuffer[128];
+ ULONG ulBytes;
+ USHORT uOp = 0;
+ USHORT uIndicator;
+ ULONG ulItems;
+ ULONG i;
+
+ ::DrgAccessDraginfo(m_pDragInfo);
+ switch(m_pDragInfo->usOperation)
+ {
+ case DO_UNKNOWN:
+ Free();
+ return (MRFROM2SHORT(DOR_NODROPOP, 0));
+
+ case DO_DEFAULT:
+ m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, 0);
+ ulBytes = ::DrgQueryStrName( m_pDragItem->hstrContainerName
+ ,128
+ ,zBuffer
+ );
+ if (!ulBytes)
+ return (MRFROM2SHORT(DOR_NODROPOP, 0));
+ else
+ uOp = DO_MOVE;
+ break;
+
+ case DO_COPY:
+ case DO_MOVE:
+ uOp = m_pDragInfo->usOperation;
+ break;
+ }
+ uIndicator = DOR_DROP;
+ ulItems = (ULONG)::DrgQueryDragitemCount(m_pDragInfo);
+ for (i = 0; i < ulItems; i++)
+ {
+ m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, i);
+ if (((m_pDragItem->fsSupportedOps & DO_COPYABLE) &&
+ (uOp == (USHORT)DO_COPY)) ||
+ ((m_pDragItem->fsSupportedOps & DO_MOVEABLE) &&
+ (uOp == (USHORT)DO_COPY)))
+ {
+ if (::DrgVerifyRMF(m_pDragItem, "DRM_OS2FILE", "DRF_UNKNOWN"))
+ uIndicator = (USHORT)DOR_DROP;
+ else
+ uIndicator = (USHORT)DOR_NEVERDROP;
+ }
+ }
+ Free();
+ return (MRFROM2SHORT(uIndicator, uOp));
+} // end of CIDropTarget::DragOver
+
+// #pragma page "CIDropTarget::Drop"
+/////////////////////////////////////////////////////////////////////////////
+//
+// CIDropTarget::Drop
+//
+// Instructs the drop target to paste data that was just now dropped on it.
+//
+// PARAMETERS
+// pIDataSource -- the data to paste
+// dwKeyState -- kbd & mouse state
+// pt -- mouse coordinates
+// pdwEffect -- effect flag
+//
+// RETURN VALUE
+// STDMETHODIMP S_OK
+//
+/////////////////////////////////////////////////////////////////////////////
+MRESULT CIDropTarget::Drop ()
+{
+ char zBuffer[128];
+ ULONG ulBytes;
+ USHORT uOp = 0;
+ USHORT uIndicator;
+ ULONG ulItems;
+ ULONG i;
+
+ ::DrgAccessDraginfo(m_pDragInfo);
+ switch(m_pDragInfo->usOperation)
+ {
+ case DO_UNKNOWN:
+ Free();
+ return (MRFROM2SHORT(DOR_NODROPOP, 0));
+
+ case DO_DEFAULT:
+ m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, 0);
+ ulBytes = ::DrgQueryStrName( m_pDragItem->hstrContainerName
+ ,128
+ ,zBuffer
+ );
+ if (!ulBytes)
+ return (MRFROM2SHORT(DOR_NODROPOP, 0));
+ else
+ uOp = DO_MOVE;
+ break;
+
+ case DO_COPY:
+ case DO_MOVE:
+ uOp = m_pDragInfo->usOperation;
+ break;
+ }
+ uIndicator = DOR_DROP;
+ ulItems = (ULONG)::DrgQueryDragitemCount(m_pDragInfo);
+ for (i = 0; i < ulItems; i++)
+ {
+ m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, i);
+ if (((m_pDragItem->fsSupportedOps & DO_COPYABLE) &&
+ (uOp == (USHORT)DO_COPY)) ||
+ ((m_pDragItem->fsSupportedOps & DO_MOVEABLE) &&
+ (uOp == (USHORT)DO_COPY)))
+ {
+ if (::DrgVerifyRMF(m_pDragItem, "DRM_OS2FILE", "DRF_UNKNOWN"))
+ uIndicator = (USHORT)DOR_DROP;
+ else
+ uIndicator = (USHORT)DOR_NEVERDROP;
+ }
+ }
+
+ //
+ // First ask the drop target if it wants data
+ //
+ if (m_pTarget->OnDrop( m_pDragInfo->xDrop
+ ,m_pDragInfo->yDrop
+ ))
+ {
+ wxDragResult eRc = wxDragNone;
+
+ //
+ // And now it has the data
+ //
+ eRc = m_pTarget->OnData( m_pDragInfo->xDrop
+ ,m_pDragInfo->yDrop
+ ,eRc
+ );
+ }
+ //else: OnDrop() returned false, no need to copy data
+
+ //
+ // Release the held object
+ //
+ Free();
+ return (MRFROM2SHORT(uIndicator, uOp));
+} // end of CIDropTarget::Drop
+