// Name : wxIDropTarget::DragOver // Purpose : Indicates that the mouse was moved inside the window represented // by this drop target. // Returns : S_OK // Params : [in] DWORD grfKeyState kbd & mouse state // [in] POINTL pt mouse coordinates // [in/out]LPDWORD pdwEffect current effect flag // Notes : We're called on every WM_MOUSEMOVE, so this function should be // very efficient. STDMETHODIMP wxIDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { // there are too many of them... wxLogDebug("IDropTarget::DragOver"); wxDragResult result; if ( m_pIDataObject ) { result = ConvertDragEffectToResult( GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction(), *pdwEffect)); } else { // can't accept data anyhow normally result = wxDragNone; } if ( result != wxDragNone ) { // we need client coordinates to pass to wxWin functions if ( !ScreenToClient(m_hwnd, (POINT *)&pt) ) { wxLogLastError(wxT("ScreenToClient")); } *pdwEffect = ConvertDragResultToEffect( m_pTarget->OnDragOver(pt.x, pt.y, result) ); } else { *pdwEffect = DROPEFFECT_NONE; } return S_OK; }
// Name : wxIDropTarget::DragEnter // Purpose : Called when the mouse enters the window (dragging something) // Returns : S_OK // Params : [in] IDataObject *pIDataSource : source data // [in] DWORD grfKeyState : kbd & mouse state // [in] POINTL pt : mouse coordinates // [in/out]DWORD *pdwEffect : effect flag // In: Supported effects // Out: Resulting effect // Notes : STDMETHODIMP wxIDropTarget::DragEnter(IDataObject *pIDataSource, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { wxLogTrace(wxTRACE_OleCalls, wxT("IDropTarget::DragEnter")); wxASSERT_MSG( m_pIDataObject == NULL, wxT("drop target must have data object") ); // show the list of formats supported by the source data object for the // debugging purposes, this is quite useful sometimes - please don't remove #if 0 IEnumFORMATETC *penumFmt; if ( SUCCEEDED(pIDataSource->EnumFormatEtc(DATADIR_GET, &penumFmt)) ) { FORMATETC fmt; while ( penumFmt->Next(1, &fmt, NULL) == S_OK ) { wxLogDebug(wxT("Drop source supports format %s"), wxDataObject::GetFormatName(fmt.cfFormat)); } penumFmt->Release(); } else { wxLogLastError(wxT("IDataObject::EnumFormatEtc")); } #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); // get hold of the data object m_pIDataObject = pIDataSource; m_pIDataObject->AddRef(); // 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)) ) ); return S_OK; }
// Name : wxIDropTarget::Drop // Purpose : Instructs the drop target to paste data that was just now // dropped on it. // Returns : S_OK // Params : [in] IDataObject *pIDataSource the data to paste // [in] DWORD grfKeyState kbd & mouse state // [in] POINTL pt where the drop occurred? // [in/out]DWORD *pdwEffect operation effect // Notes : STDMETHODIMP wxIDropTarget::Drop(IDataObject *pIDataSource, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { wxLogTrace(wxTRACE_OleCalls, wxT("IDropTarget::Drop")); // TODO I don't know why there is this parameter, but so far I assume // that it's the same we've already got in DragEnter wxASSERT( m_pIDataObject == pIDataSource ); // we need client coordinates to pass to wxWin functions if ( !ScreenToClient(m_hwnd, (POINT *)&pt) ) { wxLogLastError(wxT("ScreenToClient")); } // first ask the drop target if it wants data if ( m_pTarget->OnDrop(pt.x, pt.y) ) { // it does, so give it the data source m_pTarget->MSWSetDataSource(pIDataSource); // and now it has the data wxDragResult rc = ConvertDragEffectToResult( GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction(), *pdwEffect)); rc = m_pTarget->OnData(pt.x, pt.y, rc); if ( wxIsDragResultOk(rc) ) { // operation succeeded *pdwEffect = ConvertDragResultToEffect(rc); } else { *pdwEffect = DROPEFFECT_NONE; } } else { // OnDrop() returned false, no need to copy data *pdwEffect = DROPEFFECT_NONE; } // release the held object RELEASE_AND_NULL(m_pIDataObject); return S_OK; }
// Name : wxIDropTarget::DragLeave // Purpose : Informs the drop target that the operation has left its window. // Returns : S_OK // Notes : good place to do any clean-up STDMETHODIMP wxIDropTarget::DragLeave() { wxLogTrace(wxTRACE_OleCalls, wxT("IDropTarget::DragLeave")); // remove the UI feedback m_pTarget->OnLeave(); // release the held object RELEASE_AND_NULL(m_pIDataObject); return S_OK; }
bool CIDropTarget::DragLeave() { // // Remove the UI feedback // m_pTarget->OnLeave(); // // Release the held object // Free(); return true; } // end of CIDropTarget::DragLeave
// #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