// @pymethod |PyIDataObject|SetData|Sets the data that the object will return. PyObject *PyIDataObject::SetData(PyObject *self, PyObject *args) { IDataObject *pIDO = GetI(self); if ( pIDO == NULL ) return NULL; FORMATETC formatetc; PyObject *obpformatetc; // @pyparm <o PyFORMATETC>|pformatetc||Tuple representing a FORMATETC struct describing the type of data to be set PyObject *obmedium; PySTGMEDIUM *pymedium; // @pyparm <o PySTGMEDIUM>|pmedium||The data to be placed in the object // @pyparm boolean|fRelease||If True, transfers ownership of the data to the object. If False, caller is responsible for releasing the STGMEDIUM. BOOL fRelease; if ( !PyArg_ParseTuple(args, "OOi:SetData", &obpformatetc, &obmedium, &fRelease) ) return NULL; BOOL bPythonIsHappy = TRUE; if (bPythonIsHappy && !PyObject_AsFORMATETC( obpformatetc, &formatetc )) bPythonIsHappy = FALSE; if (bPythonIsHappy && !PyObject_AsPySTGMEDIUM( obmedium, &pymedium )) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDO->SetData( &formatetc, &pymedium->medium, fRelease ); PY_INTERFACE_POSTCALL; if (fRelease) pymedium->DropOwnership(); if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDO, IID_IDataObject ); Py_INCREF(Py_None); return Py_None; }
// copy the data from the data source to the target data object bool wxDropTarget::GetData() { wxDataFormat format = MSWGetSupportedFormat(m_pIDataSource); if ( format == wxDF_INVALID ) { // this is strange because IsAcceptedData() succeeded previously! wxFAIL_MSG(wxT("strange - did supported formats list change?")); return false; } STGMEDIUM stm; FORMATETC fmtMemory; fmtMemory.cfFormat = format; fmtMemory.ptd = NULL; fmtMemory.dwAspect = DVASPECT_CONTENT; fmtMemory.lindex = -1; fmtMemory.tymed = TYMED_HGLOBAL; // TODO to add other media bool rc = false; HRESULT hr = m_pIDataSource->GetData(&fmtMemory, &stm); if ( SUCCEEDED(hr) ) { IDataObject *dataObject = m_dataObject->GetInterface(); hr = dataObject->SetData(&fmtMemory, &stm, TRUE); if ( SUCCEEDED(hr) ) { rc = true; } else { wxLogApiError(wxT("IDataObject::SetData()"), hr); } } else { wxLogApiError(wxT("IDataObject::GetData()"), hr); } return rc; }
// The user started to move a link in the trace ctl int POTraceCtl::OnLinkDragBegin(const String& strUrl) { int nDragResult = dragNone; /////////////////////////////////////////////////////////// // Allocate resource for the data to share between PngOptimizer and the target application // Here it will be some bytes to store a file path HGLOBAL hgDrop = CreateDropFilesW(strUrl); ///////////////////////////////////////////////////////// FORMATETC etc; etc.cfFormat = CF_HDROP; // CLIPFORMAT etc.ptd = NULL; // DVTARGETDEVICE* etc.dwAspect = DVASPECT_CONTENT; // DWORD etc.lindex = -1; // LONG etc.tymed = TYMED_HGLOBAL; // DWORD STGMEDIUM med; med.tymed = TYMED_HGLOBAL; med.hGlobal = hgDrop; med.pUnkForRelease = NULL; IDataObject* pDataObject = new PlopDataObject; if( pDataObject ) { pDataObject->SetData(&etc, &med, TRUE); IDropSource* pDropSource = new PlopDropSource; if( pDropSource ) { // Forbid drag-and-drop on ourself ::DragAcceptFiles( ::GetParent(m_handle), FALSE); // DoDragDrop will manage the rest of the action and will return when a drag-and-drop action is done DWORD nEffect = 0; HRESULT hr = ::DoDragDrop(pDataObject, pDropSource, DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK, &nEffect); // Unless an optimization is in progress, enable again drag-and-drop on ourself if( !m_pApp->IsJobRunning() ) { ::DragAcceptFiles( ::GetParent(m_handle), TRUE); } if( hr == DRAGDROP_S_DROP ) { // Testing proved that we cannot rely on the return code given by Windows to know the exact // operation that occurred during DoDragDrop. It depends on the target application, // it depends on the Windows version and maybe the position of the stars in the sky // So we check ourselves if DoDragDrop performed a copy or a move by testing if our file is still here if( !File::Exists(strUrl) ) { // The source file does not exist anymore, then it was a move operation nDragResult = dragMove; } else { nDragResult = dragCopy; } } pDropSource->Release(); } pDataObject->Release(); } GlobalFree(hgDrop); return nDragResult; }