void _ecore_win32_dnd_drop_source_free(void *drop_source) { if (!drop_source) return; IDropSource *object = (IDropSource *)drop_source; object->Release(); }
void Explorerplusplus::OnAddressBarBeginDrag(void) { IDragSourceHelper *pDragSourceHelper = NULL; IDropSource *pDropSource = NULL; HRESULT hr; hr = CoCreateInstance(CLSID_DragDropHelper,NULL,CLSCTX_ALL, IID_IDragSourceHelper,(LPVOID *)&pDragSourceHelper); if(SUCCEEDED(hr)) { hr = CreateDropSource(&pDropSource,DRAG_TYPE_LEFTCLICK); if(SUCCEEDED(hr)) { LPITEMIDLIST pidlDirectory = m_pActiveShellBrowser->QueryCurrentDirectoryIdl(); FORMATETC ftc[2]; STGMEDIUM stg[2]; SetFORMATETC(&ftc[0],(CLIPFORMAT)RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR), NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL); HGLOBAL hglb = GlobalAlloc(GMEM_MOVEABLE,1000); FILEGROUPDESCRIPTOR *pfgd = static_cast<FILEGROUPDESCRIPTOR *>(GlobalLock(hglb)); pfgd->cItems = 1; FILEDESCRIPTOR *pfd = (FILEDESCRIPTOR *)((LPBYTE)pfgd + sizeof(UINT)); /* File information (name, size, date created, etc). */ pfd[0].dwFlags = FD_ATTRIBUTES|FD_FILESIZE; pfd[0].dwFileAttributes = FILE_ATTRIBUTE_NORMAL; pfd[0].nFileSizeLow = 16384; pfd[0].nFileSizeHigh = 0; /* The name of the file will be the folder name, followed by .lnk. */ TCHAR szDisplayName[MAX_PATH]; GetDisplayName(pidlDirectory,szDisplayName,SHGDN_INFOLDER); StringCchCat(szDisplayName,SIZEOF_ARRAY(szDisplayName),_T(".lnk")); StringCchCopy(pfd[0].cFileName,SIZEOF_ARRAY(pfd[0].cFileName),szDisplayName); GlobalUnlock(hglb); stg[0].pUnkForRelease = 0; stg[0].hGlobal = hglb; stg[0].tymed = TYMED_HGLOBAL; /* File contents. */ SetFORMATETC(&ftc[1],(CLIPFORMAT)RegisterClipboardFormat(CFSTR_FILECONTENTS), NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL); hglb = GlobalAlloc(GMEM_MOVEABLE,16384); IShellLink *pShellLink = NULL; IPersistStream *pPersistStream = NULL; HRESULT hr; hr = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER, IID_IShellLink,(LPVOID*)&pShellLink); if(SUCCEEDED(hr)) { TCHAR szPath[MAX_PATH]; GetDisplayName(pidlDirectory,szPath,SHGDN_FORPARSING); pShellLink->SetPath(szPath); hr = pShellLink->QueryInterface(IID_IPersistStream,(LPVOID*)&pPersistStream); if(SUCCEEDED(hr)) { IStream *pStream = NULL; CreateStreamOnHGlobal(hglb,FALSE,&pStream); hr = pPersistStream->Save(pStream,TRUE); } } GlobalUnlock(hglb); stg[1].pUnkForRelease = 0; stg[1].hGlobal = hglb; stg[1].tymed = TYMED_HGLOBAL; IDataObject *pDataObject = NULL; POINT pt = {0,0}; hr = CreateDataObject(ftc,stg,&pDataObject,2); pDragSourceHelper->InitializeFromWindow(m_hAddressBar,&pt,pDataObject); DWORD dwEffect; DoDragDrop(pDataObject,pDropSource,DROPEFFECT_LINK,&dwEffect); CoTaskMemFree(pidlDirectory); pDataObject->Release(); pDropSource->Release(); } pDragSourceHelper->Release(); } }
// 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; }