// 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; }