// 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; }
void CEdit::OnDragOver( LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { CEditView *pView; int nBuffCol, nRow; *pdwEffect = GetDropEffect( pIDataSource, grfKeyState, pt, pView, nBuffCol, nRow ); if ( *pdwEffect != DROPEFFECT_NONE ) { RECT rcDragCaret; m_Selection.GetCaretRect( pView, nBuffCol, nRow, rcDragCaret ); if ( !EqualRect( &rcDragCaret, &m_rcDragCaret ) ) { // erase old caret DrawDragCaret( FALSE ); m_rcDragCaret = rcDragCaret; // draw new caret DrawDragCaret( FALSE ); } } else { // erase old caret DrawDragCaret( TRUE ); } }
void CEdit::OnDragEnter( LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { CEditView *pDontCare; SetRectEmpty( &m_rcDragCaret ); int nDontCare1, nDontCare2; *pdwEffect = GetDropEffect( pIDataSource, grfKeyState, pt, pDontCare, nDontCare1, nDontCare2 ); }
NS_IMETHODIMP DataTransfer::GetDropEffect(nsAString& aDropEffect) { nsString dropEffect; GetDropEffect(dropEffect); aDropEffect = dropEffect; return NS_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; }
DROPEFFECT CArtOleDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { return GetDropEffect(pDataObject, dwKeyState); }
BOOL CEdit::OnDrop( LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { CEditView *pView; int nBuffCol, nRow; *pdwEffect = GetDropEffect( pIDataSource, grfKeyState, pt, pView, nBuffCol, nRow ); m_bDroppedHere = TRUE; BOOL bDropped = FALSE; if ( *pdwEffect != DROPEFFECT_NONE ) { FORMATETC fe = { CLIP_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stgm; if ( !SUCCEEDED( pIDataSource->GetData( &fe, &stgm ) ) ) { // data could not be retrieved m_Selection.SetEmptySelection( nBuffCol, nRow ); m_Selection.ShowCaret(); return FALSE; } HGLOBAL hMem = stgm.hGlobal; ASSERT( hMem ); LPCTSTR pszText = ( LPCTSTR ) GlobalLock( hMem ); m_Buffer.BeginEdit( m_Selection.GetEndRow(), m_Selection.GetEndCol() ); if ( pszText && IsDragAndDropping() ) { // we are dragging and dropping from within this control -- be careful how // the *current* selection is handled POINT ptClient = { pt.x, pt.y }; ScreenToClient( m_hWnd, &ptClient ); if ( PtInSelection( ptClient.x, ptClient.y, FALSE ) ) { m_Selection.SetEmptySelection( nBuffCol, nRow ); } else { BOOL bMove = HAS_FLAG( *pdwEffect, DROPEFFECT_MOVE ); int nStartRow, nStartCol, nEndRow, nEndCol; m_Selection.GetNormalizedBufferSelection( nStartCol, nStartRow, nEndCol, nEndRow ); if (nRow == nStartRow && nBuffCol == nStartCol) { // nothing really to do -- the source and destination are identical. // We do however need to erase the drag insertion caret. DamageSelection(FALSE); } else if ( ( nRow < nStartRow ) || ( nRow == nStartRow && nBuffCol < nStartCol ) ) { // dragging before the selection -- delete the selection first (if move) if ( bMove ) DeleteSelection( FALSE, FALSE ); m_Selection.SetEmptySelection( nBuffCol, nRow ); ReplaceSelection( pszText, FALSE, TRUE, TRUE ); } else { // dragging after the selection -- insert the new text first m_Selection.SetEmptySelection( nBuffCol, nRow ); ReplaceSelection( pszText, FALSE, TRUE, TRUE ); int nStartRowNew, nStartColNew, nEndRowNew, nEndColNew; m_Selection.GetNormalizedBufferSelection( nStartColNew, nStartRowNew, nEndColNew, nEndRowNew ); if ( bMove ) { m_Selection.SetExtendedSelection( nStartCol, nStartRow, nEndCol, nEndRow ); DeleteSelection( FALSE, FALSE ); } // we want to select the dropped text, but we must first factor in the // shift caused by the text that was just deleted. if ( nStartRowNew == nEndRow ) { ASSERT( nStartColNew >= nEndCol ); if ( nStartRow == nEndRow ) nStartColNew -= nEndCol - nStartCol; else if ( nStartRowNew == nEndRow ) nStartColNew = nStartCol + nStartColNew - nEndCol; else nStartColNew -= nEndCol; } nStartRowNew -= nEndRow - nStartRow; if ( nEndRowNew == nEndRow ) { ASSERT( nEndColNew > nEndCol ); if ( nStartRow == nEndRow ) nEndColNew -= nEndCol - nStartCol; else nEndColNew -= nEndCol; } nEndRowNew -= nEndRow - nStartRow; // select the dropped text m_Selection.SetExtendedSelection( nStartColNew, nStartRowNew, nEndColNew, nEndRowNew ); } } } else { // data came from another window -- just insert it as usual -- the other window // will remove the text if a move m_Selection.SetEmptySelection( nBuffCol, nRow ); ReplaceSelection( pszText, FALSE, TRUE, TRUE ); } if ( m_pActiveView != pView ) { SetActiveView( pView ); } m_Buffer.EndEdit( m_Selection.GetEndRow(), m_Selection.GetEndCol() ); GlobalUnlock( hMem ); if ( !stgm.pUnkForRelease ) { // provider of data decided that we should release the data ReleaseStgMedium( &stgm ); } bDropped = TRUE; } m_Selection.ShowCaret(); return bDropped; }