CefBrowserHost::DragOperationsMask DropTargetWin::StartDragging( CefRefPtr<CefBrowser> browser, CefRefPtr<CefDragData> drag_data, void* hbitmap, int imgcx, int imgcy, int imgx, int imgy, CefRenderHandler::DragOperationsMask allowed_ops, int x, int y) { CComPtr<IDataObject> dataObject; DWORD resEffect = DROPEFFECT_NONE; if (DragDataToDataObject(drag_data, &dataObject)) { IDragSourceHelper* sourceHelper = DragHelper(); HRESULT hr; if (sourceHelper) { SHDRAGIMAGE sdi; SIZE img_size{ imgcx, imgcy }; sdi.sizeDragImage = img_size; sdi.crColorKey = 0xFFFFFFFF; sdi.hbmpDragImage = (HBITMAP)hbitmap; POINT img_pt{imgx, imgy}; sdi.ptOffset = img_pt; hr = sourceHelper->InitializeFromBitmap(&sdi, dataObject); } CComPtr<IDropSource> dropSource = DropSourceWin::Create(); DWORD effect = DragOperationToDropEffect(allowed_ops); current_drag_data_ = drag_data->Clone(); current_drag_data_->ResetFileContents(); HRESULT res = DoDragDrop(dataObject, dropSource, effect, &resEffect); if (res != DRAGDROP_S_DROP) resEffect = DROPEFFECT_NONE; current_drag_data_ = NULL; } return DropEffectToDragOperation(resEffect); }
NS_IMETHODIMP nsDragService::UpdateDragImage(nsIDOMNode* aImage, int32_t aImageX, int32_t aImageY) { if (!mDataObject) { return NS_OK; } nsBaseDragService::UpdateDragImage(aImage, aImageX, aImageY); IDragSourceHelper *pdsh; if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, nullptr, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, (void**)&pdsh))) { SHDRAGIMAGE sdi; if (CreateDragImage(mSourceNode, nullptr, &sdi)) { nsNativeDragTarget::DragImageChanged(); if (FAILED(pdsh->InitializeFromBitmap(&sdi, mDataObject))) DeleteObject(sdi.hbmpDragImage); } pdsh->Release(); } return NS_OK; }
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(); } }
//------------------------------------------------------------------------- NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupportsArray *anArrayTransferables, nsIScriptableRegion *aRegion, PRUint32 aActionType) { nsresult rv = nsBaseDragService::InvokeDragSession(aDOMNode, anArrayTransferables, aRegion, aActionType); NS_ENSURE_SUCCESS(rv, rv); // Try and get source URI of the items that are being dragged nsIURI *uri = nsnull; nsCOMPtr<nsIDocument> doc(do_QueryInterface(mSourceDocument)); if (doc) { uri = doc->GetDocumentURI(); } PRUint32 numItemsToDrag = 0; rv = anArrayTransferables->Count(&numItemsToDrag); if (!numItemsToDrag) return NS_ERROR_FAILURE; // The clipboard class contains some static utility methods that we // can use to create an IDataObject from the transferable // if we're dragging more than one item, we need to create a // "collection" object to fake out the OS. This collection contains // one |IDataObject| for each transferable. If there is just the one // (most cases), only pass around the native |IDataObject|. nsRefPtr<IDataObject> itemToDrag; if (numItemsToDrag > 1) { nsDataObjCollection * dataObjCollection = new nsDataObjCollection(); if (!dataObjCollection) return NS_ERROR_OUT_OF_MEMORY; itemToDrag = dataObjCollection; for (PRUint32 i=0; i<numItemsToDrag; ++i) { nsCOMPtr<nsISupports> supports; anArrayTransferables->GetElementAt(i, getter_AddRefs(supports)); nsCOMPtr<nsITransferable> trans(do_QueryInterface(supports)); if (trans) { nsRefPtr<IDataObject> dataObj; rv = nsClipboard::CreateNativeDataObject(trans, getter_AddRefs(dataObj), uri); NS_ENSURE_SUCCESS(rv, rv); // Add the flavors to the collection object too rv = nsClipboard::SetupNativeDataObject(trans, dataObjCollection); NS_ENSURE_SUCCESS(rv, rv); dataObjCollection->AddDataObject(dataObj); } } } // if dragging multiple items else { nsCOMPtr<nsISupports> supports; anArrayTransferables->GetElementAt(0, getter_AddRefs(supports)); nsCOMPtr<nsITransferable> trans(do_QueryInterface(supports)); if (trans) { rv = nsClipboard::CreateNativeDataObject(trans, getter_AddRefs(itemToDrag), uri); NS_ENSURE_SUCCESS(rv, rv); } } // else dragging a single object // Create a drag image if support is available IDragSourceHelper *pdsh; if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, (void**)&pdsh))) { SHDRAGIMAGE sdi; if (CreateDragImage(aDOMNode, aRegion, &sdi)) { if (FAILED(pdsh->InitializeFromBitmap(&sdi, itemToDrag))) DeleteObject(sdi.hbmpDragImage); } pdsh->Release(); } // Kick off the native drag session return StartInvokingDragSession(itemToDrag, aActionType); }