STDMETHODIMP QOleDataObject::EnumFormatEtc( DWORD dwDir, IEnumFORMATETC **ppenumFormatEtc ) { if ( dwDir == DATADIR_SET ) return E_NOTIMPL; int count = 0; while ( m_dragObj->format( count ) ) count++; int *formats = new int[ count ]; for ( int i = 0; i < count; i++ ) { const char *mime = m_dragObj->format( i ); QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { int cf = c->cfFor( mime ); if ( cf ) { formats[ i ] = cf; break; } } } qIEnumFORMATETC *pEnum = new qIEnumFORMATETC( formats, count ); pEnum->AddRef(); *ppenumFormatEtc = pEnum; delete[] formats; return ResultFromScode( S_OK ); }
STDMETHODIMP QOleDataObject::GetDataHere( FORMATETC *pformatetc, STGMEDIUM *pmedium ) { // is data is in our format? HRESULT hr = QueryGetData( pformatetc ); if ( hr != S_OK ) return hr; if ( pmedium->tymed != TYMED_HGLOBAL ) return DV_E_TYMED; if ( !pmedium->hGlobal ) return STG_E_MEDIUMFULL; HGLOBAL hGlobal = pmedium->hGlobal; uint size = GlobalSize( hGlobal ); int cf = pformatetc->cfFormat; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { const char * mime = c->mimeFor( cf ); if ( mime && m_dragObj->provides( mime ) ) { QByteArray ba = m_dragObj->encodedData( mime ); if ( ba.size() > size ) return STG_E_MEDIUMFULL; memcpy ( GlobalLock ( hGlobal ), ba.data(), ba.size() ); GlobalUnlock ( hGlobal ); return S_OK; } } return E_UNEXPECTED; }
STDMETHODIMP QOleDataObject::QueryGetData( FORMATETC *pformatetc ) { #ifdef DEBUG_QDND_SRC qDebug( "QOleDataObject::QueryGetData( %p )", pformatetc ); #endif if ( !pformatetc ) { return E_INVALIDARG; } if ( pformatetc->lindex != -1 ) { return DV_E_LINDEX; } if ( pformatetc->dwAspect != DVASPECT_CONTENT ) { return DV_E_DVASPECT; } int tymed = pformatetc->tymed; /* Currently we only support HGLOBAL */ if ( !( tymed & TYMED_HGLOBAL ) ) { return DV_E_TYMED; } int cf = pformatetc->cfFormat; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { const char * mime = c->mimeFor( cf ); if ( mime && m_dragObj->provides( mime ) ) { return S_OK; } } return DV_E_FORMATETC; }
STDMETHODIMP QOleDataObject::GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium ) { // is data is in our format? HRESULT hr = QueryGetData( pformatetcIn ); if ( hr != S_OK ) return hr; int cf = pformatetcIn->cfFormat; pmedium->tymed = TYMED_HGLOBAL; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { const char * mime = c->mimeFor( cf ); if ( mime && m_dragObj->provides( mime ) ) { QByteArray ba = m_dragObj->encodedData( mime ); ba = c->convertFromMime( ba, mime, cf ); HGLOBAL hGlobal = GlobalAlloc ( GMEM_MOVEABLE | GMEM_SHARE, ba.size() ); if ( !hGlobal ) return E_OUTOFMEMORY; memcpy ( GlobalLock ( hGlobal ), ba.data(), ba.size() ); GlobalUnlock ( hGlobal ); pmedium->hGlobal = hGlobal; pmedium->pUnkForRelease = NULL; return S_OK; } } return E_UNEXPECTED; }
bool QDropEvent::provides( const char * mimeType ) const { #ifdef DEBUG_QDND_WIN qDebug( "QDropEvent::provides ( %s )", mimeType ); #endif if ( !pIDataObject ) return false; FORMATETC fmtMemory = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; /* Search all available mimes for mimeType and look if pIDataObject can give us data in this clipboard format */ QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { int cf = c->cfFor( mimeType ); if ( c->canConvert( mimeType, cf ) ) { fmtMemory.cfFormat = cf; if ( pIDataObject->QueryGetData( &fmtMemory ) == S_OK ) { return true; } } } return false; }
QVariant QClipboardWatcher::retrieveData_sys(const QString &mimeType, QVariant::Type type) const { QVariant result; IDataObject * pDataObj = 0; if (OleGetClipboard(&pDataObj) != S_OK && !pDataObj) // Sanity return result; QWindowsMime *converter = QWindowsMime::converterToMime(mimeType, pDataObj); if (converter) result = converter->convertToMime(mimeType, pDataObj, type); pDataObj->Release(); return result; }
/*********************************************** QDropEvent ************************************************/ QByteArray QDropEvent::encodedData( const char * format ) const { #ifdef DEBUG_QDND_WIN qDebug( "QDropEvent::encodedData ( %s )", format ); #endif QByteArray ba; /* Currently we only support TYMED_HGLOBAL ... */ FORMATETC fmtMemory = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stm; if ( !pIDataObject ) { return ba; } QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { int cf = c->cfFor( format ); if ( c->canConvert( format, cf ) ) { fmtMemory.cfFormat = cf; if ( pIDataObject->QueryGetData( &fmtMemory ) == S_OK ) { HRESULT hr = pIDataObject->GetData( &fmtMemory, &stm ); if ( ( hr != S_OK ) || ( !stm.hGlobal ) ) continue; QByteArray data; QBuffer buf ( data ); buf.open( IO_WriteOnly ); buf.writeBlock ( ( char* ) GlobalLock( stm.hGlobal ), GlobalSize ( stm.hGlobal ) ); buf.close(); GlobalUnlock ( stm.hGlobal ); ReleaseStgMedium( &stm ); ba = c->convertToMime( data, format, cf ); ReleaseStgMedium( &stm ); return ba; } } } return ba; }
const char* QDropEvent::format( int n ) const { #ifdef DEBUG_QDND_WIN qDebug( "QDropEvent::format ( %d )", n ); #endif if ( !pIDataObject ) return NULL; FORMATETC fmtMemory = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; if ( n >= 0 ) { QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { for ( int i = 0; i < c->countCf(); i++ ) { int cf = c->cf( i ); fmtMemory.cfFormat = cf; if ( pIDataObject->QueryGetData( &fmtMemory ) == S_OK ) { if ( n == 0 ) { #ifdef DEBUG_QDND_WIN qDebug( "format: %s", c->mimeFor( cf ) ); #endif return c->mimeFor( cf ); } n--; } } } } return NULL; }
STDMETHODIMP QOleDropTarget::Drop( LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { #ifdef DEBUG_QDND_TGT qDebug( "QOleDropTarget::Drop( %p, %d, %d/%d, %d )", pIDataSource, grfKeyState, pt.x, pt.y, *pdwEffect ); qDebug( "widget: %p, winID: %08x", widget, widget ? widget->winId() : 0 ); #endif if ( !qt_tryModalHelper( widget ) ) { *pdwEffect = DROPEFFECT_NONE; return NOERROR; } lastPoint = widget->mapFromGlobal( QPoint( pt.x, pt.y ) ); // grfKeyState does not all ways contain button state in the drop so if // it doesn't then use the last known button state; if ( ( grfKeyState & KEY_STATE_BUTTON_MASK ) == 0 ) grfKeyState |= lastKeyState & KEY_STATE_BUTTON_MASK; lastKeyState = grfKeyState; FORMATETC s_fmtMemory = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; /* Can we convert the data? */ bool found = false; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c && !found; c = all.next() ) { for ( int i = 0; i < c->countCf(); i++ ) { int cf = c->cf( i ); s_fmtMemory.cfFormat = cf; if ( pIDataSource->QueryGetData( &s_fmtMemory ) == S_OK ) { found = true; break; } } } if ( !found ) { return S_OK; } /* Just to be sure */ pIDataObject = pIDataSource; pIDataObject->AddRef(); QDropEvent de( lastPoint ); de.setAction( translateKeyStateToQDropAction( grfKeyState, *pdwEffect ) ); if ( global_src ) global_src->setTarget( widget ); QApplication::sendEvent( widget, &de ); pIDataObject->Release(); pIDataObject = NULL; return S_OK; }