// @pymethod int|PyIDropTarget|DragEnter|Called when an object is initially dragged into a window // @rdesc Your implementation of this function should return a shellcon.DROPEFFECT_* value indicating if the object can be accepted PyObject *PyIDropTarget::DragEnter(PyObject *self, PyObject *args) { IDropTarget *pIDT = GetI(self); if ( pIDT == NULL ) return NULL; // @pyparm <o PyIDataObject>|pDataObj||IDataObject interface that contains the object being dragged // @pyparm int|grfKeyState||Combination of win32con.MK_* flags containing keyboard modifier state POINTL pt; PyObject *obpt; // @pyparm (int, int)|pt||(x,y) Screen coordinates of cursor PyObject *obpDataObj; IDataObject *pDataObj; DWORD grfKeyState; DWORD dwEffect; // @pyparm int|pdwEffect||shellcon.DROPEFFECT_* value if ( !PyArg_ParseTuple(args, "OlOl:DragEnter", &obpDataObj, &grfKeyState, &obpt, &dwEffect) ) return NULL; BOOL bPythonIsHappy = TRUE; if (bPythonIsHappy && !PyCom_InterfaceFromPyInstanceOrObject(obpDataObj, IID_IDataObject, (void **)&pDataObj, TRUE /* bNoneOK */)) bPythonIsHappy = FALSE; if (bPythonIsHappy && !PyObject_AsPOINTL( obpt, &pt )) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDT->DragEnter( pDataObj, grfKeyState, pt, &dwEffect ); if (pDataObj) pDataObj->Release(); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDT, IID_IDropTarget ); return PyInt_FromLong(dwEffect); }
// @pymethod |PyIOleObject|InitFromData|Description of InitFromData. PyObject *PyIOleObject::InitFromData(PyObject *self, PyObject *args) { IOleObject *pIOO = GetI(self); if ( pIOO == NULL ) return NULL; // @pyparm <o PyIDataObject>|pDataObject||Description for pDataObject // @pyparm int|fCreation||Description for fCreation // @pyparm int|dwReserved||Description for dwReserved PyObject *obpDataObject; IDataObject * pDataObject; BOOL fCreation; DWORD dwReserved; if ( !PyArg_ParseTuple(args, "Oii:InitFromData", &obpDataObject, &fCreation, &dwReserved) ) return NULL; BOOL bPythonIsHappy = TRUE; if (!PyCom_InterfaceFromPyInstanceOrObject(obpDataObject, IID_IDataObject, (void **)&pDataObject, TRUE /* bNoneOK */)) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIOO->InitFromData( pDataObject, fCreation, dwReserved ); if (pDataObject) pDataObject->Release(); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return OleSetOleError(hr); Py_INCREF(Py_None); return Py_None; }
//------------------------------------------------------------------------- NS_IMETHODIMP nsClipboard::SetNativeClipboardData ( PRInt32 aWhichClipboard ) { if ( aWhichClipboard != kGlobalClipboard ) return NS_ERROR_FAILURE; mIgnoreEmptyNotification = true; // make sure we have a good transferable if (nullptr == mTransferable) { return NS_ERROR_FAILURE; } IDataObject * dataObj; if ( NS_SUCCEEDED(CreateNativeDataObject(mTransferable, &dataObj, NULL)) ) { // this add refs dataObj ::OleSetClipboard(dataObj); dataObj->Release(); } else { // Clear the native clipboard ::OleSetClipboard(NULL); } mIgnoreEmptyNotification = false; return NS_OK; }
STDMETHODIMP Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { LPCWSTR args; OutputDebugString(L"PyShellExt::Drop"); *pdwEffect = DROPEFFECT_NONE; if (pDataObj != data_obj) { OutputDebugString(L"PyShellExt::Drop - unexpected data object"); return E_FAIL; } data_obj->Release(); data_obj = NULL; if (SUCCEEDED(GetArguments(pDataObj, &args))) { OutputDebugString(args); ShellExecute(NULL, NULL, target, args, target_dir, SW_NORMAL); CoTaskMemFree((LPVOID)args); } else { OutputDebugString(L"PyShellExt::Drop - failed to get launch arguments"); } return S_OK; }
HRESULT CDataObjectViewer::OnView(HWND hwndParent, REFIID riid, LPUNKNOWN punk) { SCODE sc = NOERROR ; ASSERT(hwndParent); ENSURE(punk); if (riid != IID_IDataObject) { AfxMessageBox( _T("IDataObject interface viewer only supports IID_IDataObject") ) ; return E_INVALIDARG ; } IDataObject* pdataobj = NULL ; sc = punk->QueryInterface( riid, (void**)&pdataobj ) ; if (FAILED(sc)) { AfxMessageBox( _T("Object does not support IDataObject") ) ; return E_UNEXPECTED ; } CIDataObjectDlg* pdlg ; pdlg = new CIDataObjectDlg( hwndParent, pdataobj, riid, _T("") ) ; if (pdlg) { pdlg->DoModal() ; delete pdlg ; } pdataobj->Release() ; return sc ; }
void ShellDirectory::fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA* pw32fdata, bool do_access) { CONTEXT("ShellDirectory::fill_w32fdata_shell()"); if (do_access && !( (attribs&SFGAO_FILESYSTEM) && SUCCEEDED( SHGetDataFromIDList(_folder, pidl, SHGDFIL_FINDDATA, pw32fdata, sizeof(WIN32_FIND_DATA))) )) { WIN32_FILE_ATTRIBUTE_DATA fad; IDataObject* pDataObj; STGMEDIUM medium = {0, {0}, 0}; FORMATETC fmt = {g_Globals._cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; HRESULT hr = _folder->GetUIObjectOf(0, 1, &pidl, IID_IDataObject, 0, (LPVOID*)&pDataObj); if (SUCCEEDED(hr)) { hr = pDataObj->GetData(&fmt, &medium); pDataObj->Release(); if (SUCCEEDED(hr)) { LPCTSTR path = (LPCTSTR)GlobalLock(medium.hGlobal); // fill with drive names "C:", ... assert(_tcslen(path) < GlobalSize(medium.hGlobal)); _tcscpy(pw32fdata->cFileName, path); UINT sem_org = SetErrorMode(SEM_FAILCRITICALERRORS); if (GetFileAttributesEx(path, GetFileExInfoStandard, &fad)) { pw32fdata->dwFileAttributes = fad.dwFileAttributes; pw32fdata->ftCreationTime = fad.ftCreationTime; pw32fdata->ftLastAccessTime = fad.ftLastAccessTime; pw32fdata->ftLastWriteTime = fad.ftLastWriteTime; if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { pw32fdata->nFileSizeLow = fad.nFileSizeLow; pw32fdata->nFileSizeHigh = fad.nFileSizeHigh; } } SetErrorMode(sem_org); GlobalUnlock(medium.hGlobal); GlobalFree(medium.hGlobal); } } } if (!do_access || !(attribs&SFGAO_FILESYSTEM)) // Archiv files should not be displayed as folders in explorer view. if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER)) pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; if (attribs & SFGAO_READONLY) pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; if (attribs & SFGAO_COMPRESSED) pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_COMPRESSED; }
bool ng_playlist_view_t::do_drag_drop(WPARAM wp) { metadb_handle_list_t<pfc::alloc_fast_aggressive> data; m_playlist_api->activeplaylist_get_selected_items(data); if (data.get_count() > 0) { static_api_ptr_t<playlist_incoming_item_filter> incoming_api; IDataObject * pDataObject = incoming_api->create_dataobject(data); if (pDataObject) { //IDataObject * pDataObjectFixed = new CDataObject; #if 0 mmh::comptr_t<IEnumFORMATETC> pEnumFORMATETC; pDataObject->EnumFormatEtc(DATADIR_GET, pEnumFORMATETC.get_pp()); FORMATETC fe; memset(&fe,0,sizeof(fe)); while (S_OK == pEnumFORMATETC->Next(1, &fe, NULL)) { STGMEDIUM stgm; memset(&stgm, 0, sizeof(0)); if (SUCCEEDED(pDataObject->GetData(&fe, &stgm))) { //if (stgm.tymed != TYMED_ISTREAM) // pDataObjectFixed->SetData(&fe, &stgm, FALSE); ReleaseStgMedium(&stgm); } memset(&fe,0,sizeof(fe)); } pEnumFORMATETC.release(); #endif //pfc::com_ptr_t<IAsyncOperation> pAsyncOperation; //HRESULT hr = pDataObject->QueryInterface(IID_IAsyncOperation, (void**)pAsyncOperation.receive_ptr()); DWORD blah = DROPEFFECT_NONE; { m_dragging = true; m_DataObject = pDataObject; m_dragging_initial_playlist = m_playlist_api->get_active_playlist(); pfc::com_ptr_t<mmh::ole::IDropSource_Generic> p_IDropSource_playlist = new mmh::ole::IDropSource_Generic(get_wnd(), pDataObject, wp); HRESULT hr = DoDragDrop(pDataObject,p_IDropSource_playlist.get_ptr(),DROPEFFECT_COPY|DROPEFFECT_MOVE,&blah); //SHDoDragDrop(get_wnd(), pDataObject,NULL,DROPEFFECT_COPY|DROPEFFECT_MOVE,&blah); m_dragging=false; m_DataObject.release(); m_dragging_initial_playlist = pfc_infinite; /*if (DRAGDROP_S_DROP == hr && blah == DROPEFFECT_MOVE) m_playlist_api->playlist_remove_selection(playlist);*/ } //pDataObjectFixed->Release(); pDataObject->Release(); } } return true; }
~PyShellExt() { if (target) { CoTaskMemFree(target); } if (target_dir) { CoTaskMemFree(target_dir); } if (data_obj) { data_obj->Release(); } }
bool DesktopShellView::DoContextMenu(int x, int y) { IDataObject* selection; HRESULT hr = _pShellView->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&selection); if (FAILED(hr)) return false; PIDList pidList; hr = pidList.GetData(selection); if (FAILED(hr)) { selection->Release(); //CHECKERROR(hr); return false; } LPIDA pida = pidList; if (!pida->cidl) { selection->Release(); return false; } LPCITEMIDLIST parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]); LPCITEMIDLIST* apidl = (LPCITEMIDLIST*) alloca(pida->cidl*sizeof(LPCITEMIDLIST)); for(int i=pida->cidl; i>0; --i) apidl[i-1] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i]); hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y, _cm_ifs); selection->Release(); if (SUCCEEDED(hr)) refresh(); else CHECKERROR(hr); return true; }
HRESULT CTextObject::GetClipboard() { IDataObject* pDataObject; HRESULT hRes = OleGetClipboard(&pDataObject); if (SUCCEEDED(hRes)) { if (! SetObjectText(pDataObject)) hRes = E_FAIL; pDataObject->Release(); } return hRes; }
// process default command: look for folders and traverse into them HRESULT IShellBrowserImpl::OnDefaultCommand(IShellView* ppshv) { IDataObject* selection; HRESULT hr = ppshv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&selection); if (FAILED(hr)) return hr; PIDList pidList; hr = pidList.GetData(selection); if (FAILED(hr)) { selection->Release(); return hr; } hr = OnDefaultCommand(pidList); selection->Release(); return hr; }
bool QClipboardWatcher::hasFormat_sys(const QString &mime) const { IDataObject * pDataObj = 0; if (OleGetClipboard(&pDataObj) != S_OK && !pDataObj) // Sanity return false; bool has = QWindowsMime::converterToMime(mime, pDataObj) != 0; pDataObj->Release(); return has; }
TEST_F(iDataObjectTest, QueryInterface) { IUnknown *pUnknownOut = NULL; HRESULT hr = m_pDataObject->QueryInterface(IID_PPV_ARGS(&pUnknownOut)); EXPECT_EQ(S_OK, hr); pUnknownOut->Release(); IDataObject *pDataObjectOut = NULL; hr = m_pDataObject->QueryInterface(IID_PPV_ARGS(&pDataObjectOut)); EXPECT_EQ(S_OK, hr); pDataObjectOut->Release(); }
QStringList QClipboardWatcher::formats_sys() const { QStringList fmts; IDataObject * pDataObj = 0; if (OleGetClipboard(&pDataObj) != S_OK && !pDataObj) // Sanity return QStringList(); fmts = QWindowsMime::allMimesForFormats(pDataObj); pDataObj->Release(); return fmts; }
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; }
static void* sWin32_Get_Callback(void* iParam) { ZTuple* result = static_cast<ZTuple*>(iParam); IDataObject* theIDataObject; HRESULT theHRESULT = ::OleGetClipboard(&theIDataObject); if (SUCCEEDED(theHRESULT)) { *result = ZDragClip_Win_DataObject::sAsTuple(theIDataObject); theIDataObject->Release(); } else { result->Clear(); } return nil; }
static void* sWin32_Set_Callback(void* iParam) { const ZTuple& theTuple = *static_cast<ZTuple*>(iParam); if (theTuple.Empty()) { ::OleFlushClipboard(); } else { ZDragClip_Win_DataObject* theDataObject = new ZDragClip_Win_DataObject(theTuple); theDataObject->AddRef(); IDataObject* theIDataObject; if (SUCCEEDED(theDataObject->QueryInterface(IID_IDataObject, (void**)&theIDataObject)) && theIDataObject) { HRESULT theHRESULT = ::OleSetClipboard(theIDataObject); theIDataObject->Release(); } theDataObject->Release(); } return nil; }
// @pymethod |PyIDocHostUIHandler|FilterDataObject|Description of FilterDataObject. PyObject *PyIDocHostUIHandler::FilterDataObject(PyObject *self, PyObject *args) { IDocHostUIHandler *pIDHUIH = GetI(self); if ( pIDHUIH == NULL ) return NULL; // @pyparm <o PyIDataObject>|pDO||Description for pDO PyObject *obpDO; IDataObject * pDO; IDataObject * ppDORet; if ( !PyArg_ParseTuple(args, "O:FilterDataObject", &obpDO) ) return NULL; if (!PyCom_InterfaceFromPyInstanceOrObject(obpDO, IID_IDataObject, (void **)&pDO, TRUE /* bNoneOK */)) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDHUIH->FilterDataObject( pDO, &ppDORet ); if (pDO) pDO->Release(); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDHUIH, IID_IDocHostUIHandler ); return PyCom_PyObjectFromIUnknown(ppDORet, IID_IDataObject, FALSE); }
void Explorerplusplus::OnTreeViewPaste(void) { HTREEITEM hItem; LPITEMIDLIST pidl = NULL; TCHAR szFullFileName[MAX_PATH + 1]; hItem = TreeView_GetSelection(m_hTreeView); if(hItem != NULL) { IDataObject *pClipboardObject = NULL; HRESULT hr = OleGetClipboard(&pClipboardObject); if(hr == S_OK) { CDropHandler *pDropHandler = CDropHandler::CreateNew(); pidl = m_pMyTreeView->BuildPath(hItem); assert(pidl != NULL); GetDisplayName(pidl,szFullFileName,SIZEOF_ARRAY(szFullFileName),SHGDN_FORPARSING); /* Name must be double NULL terminated. */ szFullFileName[lstrlen(szFullFileName) + 1] = '\0'; pDropHandler->CopyClipboardData(pClipboardObject, m_hTreeView,szFullFileName,NULL, !m_bOverwriteExistingFilesConfirmation); CoTaskMemFree(pidl); pDropHandler->Release(); pClipboardObject->Release(); } } }
//------------------------------------------------------------------------- NS_IMETHODIMP nsClipboard::GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 aWhichClipboard ) { // make sure we have a good transferable if ( !aTransferable || aWhichClipboard != kGlobalClipboard ) return NS_ERROR_FAILURE; nsresult res; // This makes sure we can use the OLE functionality for the clipboard IDataObject * dataObj; if (S_OK == ::OleGetClipboard(&dataObj)) { // Use OLE IDataObject for clipboard operations res = GetDataFromDataObject(dataObj, 0, nullptr, aTransferable); dataObj->Release(); } else { // do it the old manual way res = GetDataFromDataObject(nullptr, 0, mWindow, aTransferable); } return res; }
/* TODO: Use CDropHandler. */ int PasteFilesFromClipboardSpecial(TCHAR *szDestination,UINT fPasteType) { IDataObject *ClipboardObject = NULL; DROPFILES *pdf = NULL; FORMATETC ftc; STGMEDIUM stg; HRESULT hr; TCHAR szFileName[MAX_PATH]; TCHAR szLinkFileName[MAX_PATH]; TCHAR szOldFileName[MAX_PATH]; int nFilesCopied = -1; int i = 0; hr = OleGetClipboard(&ClipboardObject); if(SUCCEEDED(hr)) { ftc.cfFormat = CF_HDROP; ftc.ptd = NULL; ftc.dwAspect = DVASPECT_CONTENT; ftc.lindex = -1; ftc.tymed = TYMED_HGLOBAL; hr = ClipboardObject->GetData(&ftc,&stg); if(SUCCEEDED(hr)) { pdf = (DROPFILES *)GlobalLock(stg.hGlobal); if(pdf != NULL) { nFilesCopied = DragQueryFile((HDROP)pdf, 0xFFFFFFFF,NULL,0); for(i = 0;i < nFilesCopied;i++) { DragQueryFile((HDROP)pdf,i,szOldFileName,SIZEOF_ARRAY(szOldFileName)); StringCchCopy(szLinkFileName,SIZEOF_ARRAY(szLinkFileName),szDestination); StringCchCopy(szFileName,SIZEOF_ARRAY(szFileName),szOldFileName); PathStripPath(szFileName); PathAppend(szLinkFileName,szFileName); switch(fPasteType) { case PASTE_CLIPBOARD_LINK: PathRenameExtension(szLinkFileName,_T(".lnk")); CreateLinkToFile(szOldFileName,szLinkFileName,EMPTY_STRING); break; case PASTE_CLIPBOARD_HARDLINK: CreateHardLink(szLinkFileName,szOldFileName,NULL); break; } } GlobalUnlock(stg.hGlobal); } ReleaseStgMedium(&stg); } ClipboardObject->Release(); } return nFilesCopied; }
// returns true on success, false on failure //bool InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap, HGLOBAL hGlobal) bool InsertBitmap(IRichEditOle* pRichEditOle, HENHMETAFILE hEmf) { SCODE sc; // Get the image data object // static const FORMATETC lc_format[] = { { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }//, // { CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, // { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }; STGMEDIUM lc_stgmed[] = { { TYMED_ENHMF, { (HBITMAP)hEmf }, 0 }//, // { TYMED_GDI, { hBitmap }, 0 }, // { TYMED_HGLOBAL, { (HBITMAP)hGlobal }, 0 } }; IDataObject *pods; CreateDataObject(lc_format, lc_stgmed, 1, &pods); // Get the RichEdit container site // IOleClientSite *pOleClientSite; pRichEditOle->GetClientSite(&pOleClientSite); // Initialize a Storage Object // LPLOCKBYTES lpLockBytes = NULL; sc = CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes); if (sc != S_OK) { pOleClientSite->Release(); return false; } IStorage *pStorage; sc = StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); if (sc != S_OK) { lpLockBytes->Release(); pOleClientSite->Release(); return false; } // The final ole object which will be inserted in the richedit control // IOleObject *pOleObject; sc = OleCreateStaticFromData(pods, IID_IOleObject, OLERENDER_FORMAT, (LPFORMATETC)lc_format, pOleClientSite, pStorage, (void **)&pOleObject); if (sc != S_OK) { pStorage->Release(); lpLockBytes->Release(); pOleClientSite->Release(); return false; } // all items are "contained" -- this makes our reference to this object // weak -- which is needed for links to embedding silent update. OleSetContainedObject(pOleObject, TRUE); // Now Add the object to the RichEdit // REOBJECT reobject = { 0 }; reobject.cbStruct = sizeof(REOBJECT); reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT; reobject.poleobj = pOleObject; reobject.polesite = pOleClientSite; reobject.pstg = pStorage; reobject.dwFlags = REO_BELOWBASELINE; sc = pOleObject->GetUserClassID(&reobject.clsid); if (sc != S_OK) { pOleObject->Release(); pStorage->Release(); lpLockBytes->Release(); pOleClientSite->Release(); return false; } // Insert the bitmap at the current location in the richedit control // sc = pRichEditOle->InsertObject(&reobject); // Release all unnecessary interfaces // pOleObject->Release(); pStorage->Release(); lpLockBytes->Release(); pOleClientSite->Release(); pods->Release(); return sc == S_OK; }
// 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; }
bool wxClipboard::GetData( wxDataObject& data ) { #if wxUSE_OLE_CLIPBOARD IDataObject *pDataObject = NULL; HRESULT hr = OleGetClipboard(&pDataObject); if ( FAILED(hr) || !pDataObject ) { wxLogSysError(hr, _("Failed to get data from the clipboard")); return false; } // build the list of supported formats size_t nFormats = data.GetFormatCount(wxDataObject::Set); wxDataFormat format; wxDataFormat *formats; if ( nFormats == 1 ) { // the most common case formats = &format; } else { // bad luck, need to alloc mem formats = new wxDataFormat[nFormats]; } data.GetAllFormats(formats, wxDataObject::Set); // get the data for the given formats FORMATETC formatEtc; CLIPFORMAT cf; bool result = false; // enumerate all explicit formats on the clipboard. // note that this does not include implicit / synthetic (automatically // converted) formats. #ifdef __WXDEBUG__ // get the format enumerator IEnumFORMATETC *pEnumFormatEtc = NULL; hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc); if ( FAILED(hr) || !pEnumFormatEtc ) { wxLogSysError(hr, _("Failed to retrieve the supported clipboard formats")); } else { // ask for the supported formats and see if there are any we support for ( ;; ) { ULONG nCount; hr = pEnumFormatEtc->Next(1, &formatEtc, &nCount); // don't use FAILED() because S_FALSE would pass it if ( hr != S_OK ) { // no more formats break; } cf = formatEtc.cfFormat; wxLogTrace(wxTRACE_OleCalls, wxT("Object on the clipboard supports format %s."), wxDataObject::GetFormatName(cf)); } pEnumFormatEtc->Release(); } #endif // Debug STGMEDIUM medium; // stop at the first valid format found on the clipboard for ( size_t n = 0; !result && (n < nFormats); n++ ) { // convert to NativeFormat Id cf = formats[n].GetFormatId(); // if the format is not available, try the next one // this test includes implicit / sythetic formats if ( !::IsClipboardFormatAvailable(cf) ) continue; formatEtc.cfFormat = cf; formatEtc.ptd = NULL; formatEtc.dwAspect = DVASPECT_CONTENT; formatEtc.lindex = -1; // use the appropriate tymed switch ( formatEtc.cfFormat ) { case CF_BITMAP: formatEtc.tymed = TYMED_GDI; break; #ifndef __WXWINCE__ case CF_METAFILEPICT: formatEtc.tymed = TYMED_MFPICT; break; case CF_ENHMETAFILE: formatEtc.tymed = TYMED_ENHMF; break; #endif default: formatEtc.tymed = TYMED_HGLOBAL; } // try to get data hr = pDataObject->GetData(&formatEtc, &medium); if ( FAILED(hr) ) { // try other tymed for GDI objects if ( formatEtc.cfFormat == CF_BITMAP ) { formatEtc.tymed = TYMED_HGLOBAL; hr = pDataObject->GetData(&formatEtc, &medium); } } if ( SUCCEEDED(hr) ) { // pass the data to the data object hr = data.GetInterface()->SetData(&formatEtc, &medium, true); if ( FAILED(hr) ) { wxLogDebug(wxT("Failed to set data in wxIDataObject")); // IDataObject only takes the ownership of data if it // successfully got it - which is not the case here ReleaseStgMedium(&medium); } else { result = true; } } //else: unsupported tymed? } if ( formats != &format ) { delete [] formats; } //else: we didn't allocate any memory // clean up and return pDataObject->Release(); return result; #elif wxUSE_DATAOBJ wxCHECK_MSG( wxIsClipboardOpened(), false, wxT("clipboard not open") ); wxDataFormat format = data.GetPreferredFormat(); switch ( format ) { case wxDF_TEXT: case wxDF_OEMTEXT: { wxTextDataObject& textDataObject = (wxTextDataObject &)data; char* s = (char*)wxGetClipboardData(format); if ( !s ) return false; textDataObject.SetText(wxString::FromAscii(s)); delete [] s; return true; } case wxDF_BITMAP: case wxDF_DIB: { wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data; wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data.GetPreferredFormat()); if ( !bitmap ) return false; bitmapDataObject.SetBitmap(*bitmap); delete bitmap; return true; } #if wxUSE_METAFILE case wxDF_METAFILE: { wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data; wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE); if ( !metaFile ) return false; metaFileDataObject.SetMetafile(*metaFile); delete metaFile; return true; } #endif // wxUSE_METAFILE } return false; #else // !wxUSE_DATAOBJ wxFAIL_MSG( wxT("no clipboard implementation") ); return false; #endif // wxUSE_OLE_CLIPBOARD/wxUSE_DATAOBJ }
LRESULT playlist_view::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_NCCREATE: wnd_playlist = wnd; initialised = true; list_playlist.add_item(this); g_playlist_message_window.add_ref(); break; case WM_CREATE: { pfc::com_ptr_t<IDropTarget_playlist> IDT_playlist = new IDropTarget_playlist(this); RegisterDragDrop(wnd, IDT_playlist.get_ptr()); if (true) { m_theme = IsThemeActive() && IsAppThemed() ? OpenThemeData(wnd, L"ListView") : NULL; SetWindowTheme(wnd, L"Explorer", NULL); } m_always_show_focus = config_object::g_get_data_bool_simple(standard_config_objects::bool_playback_follows_cursor, false); on_playlist_font_change(); create_header(true); drawing_enabled = true; m_cache.initialise(); } return 0; case WM_DESTROY: m_edit_save = false; exit_inline_edit(); m_cache.deinitialise(); RevokeDragDrop(wnd); SendMessage(wnd, WM_SETFONT, 0, 0); SendMessage(wnd_header, WM_SETFONT, 0, 0); { if (m_theme) CloseThemeData(m_theme); m_theme = NULL; } m_selection_holder.release(); break; case WM_NCDESTROY: g_playlist_message_window.release(); wnd_playlist = 0; initialised = false; list_playlist.remove_item(this); m_shown = false; // if (!list_playlist.get_count()) // { // g_playlist_entries.rebuild_all(); // } break; case WM_THEMECHANGED: { if (m_theme) CloseThemeData(m_theme); m_theme = IsThemeActive() && IsAppThemed() ? OpenThemeData(wnd, L"ListView") : 0; } break; case WM_SHOWWINDOW: if (wp == TRUE && lp == 0 && !m_shown) { static_api_ptr_t<playlist_manager> playlist_api; ensure_visible(playlist_api->activeplaylist_get_focus_item()); m_shown = true; } break; case WM_WINDOWPOSCHANGED: { LPWINDOWPOS lpwp = (LPWINDOWPOS)lp; if (!(lpwp->flags & SWP_NOSIZE)) { on_size(lpwp->cx, lpwp->cy); } } break; case WM_ERASEBKGND: return TRUE; break; case WM_PAINT: { PAINTSTRUCT ps; HDC dc_paint = BeginPaint(wnd, &ps); RECT rc_update, rc_playlist; get_playlist_rect(&rc_playlist); rc_update = ps.rcPaint; if (rc_update.top<rc_playlist.top) rc_update.top = rc_playlist.top; if (rc_update.bottom >= rc_update.top) { int item_height = get_item_height(); int start_item = (rc_update.top - rc_playlist.top) / item_height; int end_item = (rc_update.bottom - rc_playlist.top) / item_height; if (((end_item - start_item) + 1)*item_height < rc_update.bottom - rc_update.top) end_item++; { draw_items(dc_paint, start_item, 1 + (end_item - start_item)); } } EndPaint(wnd, &ps); } return 0; case WM_SETREDRAW: drawing_enabled = (wp != 0); return 0; case WM_MOUSEACTIVATE: if (GetFocus() != wnd) m_no_next_edit = true; return MA_ACTIVATE; case WM_UPDATEUISTATE: RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE); break; case WM_KILLFOCUS: RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); m_selection_holder.release(); break; case WM_SETFOCUS: //if (msg == WM_SETFOCUS && (HWND)wp != wnd) //m_no_next_edit = true; RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); m_selection_holder = static_api_ptr_t<ui_selection_manager>()->acquire(); m_selection_holder->set_playlist_selection_tracking(); break; case WM_GETDLGCODE: return DLGC_WANTALLKEYS; case WM_KEYDOWN: { static_api_ptr_t<playlist_manager> playlist_api; uie::window_ptr p_this = this; //DWORD vk_slash = VkKeyScan('/'); if (wp == VK_CONTROL) g_drag_lmb = true; if (m_prevent_wm_char_processing = process_keydown(msg, lp, wp, true)) return 0; else { SendMessage(wnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), NULL); if (wp == VK_HOME || wp == VK_DOWN || wp == VK_END || wp == VK_PRIOR || wp == VK_NEXT || wp == VK_UP) { int focus = playlist_api->activeplaylist_get_focus_item(); int total = playlist_api->activeplaylist_get_item_count(); if ((wp == VK_HOME || wp == VK_PRIOR || wp == VK_UP)) { // if (focus == 0) return 0; } if ((wp == VK_END || wp == VK_NEXT || wp == VK_DOWN)) { // if (focus == total - 1) return 0; } SCROLLINFO si; memset(&si, 0, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_POS; GetScrollInfo(wnd_playlist, SB_VERT, &si); int offset = 0; int scroll = scroll_item_offset; if (wp == VK_HOME) scroll = 0; else if (wp == VK_PRIOR && focus == scroll_item_offset) scroll -= si.nPage; else if (wp == VK_UP) { if (focus <= scroll_item_offset) scroll = focus - 1; else if (focus > si.nPos + si.nPage - 1) scroll = focus - 1 - si.nPage + 1; } else if (wp == VK_DOWN) { if (focus < scroll_item_offset) scroll = focus + 1; else if (focus >= si.nPos + si.nPage - 1) scroll = focus + 1 - si.nPage + 1; } else if (wp == VK_END) scroll = total - 1; else if (wp == VK_NEXT && focus == si.nPos + si.nPage - 1) scroll += si.nPage; drawing_enabled = false; si.nPos = scroll; si.fMask = SIF_POS; scroll_item_offset = SetScrollInfo(wnd_playlist, SB_VERT, &si, true); if (wp == VK_HOME) offset = 0 - focus; else if (wp == VK_PRIOR) offset = scroll_item_offset - focus; else if (wp == VK_END) offset = total - focus - 1; else if (wp == VK_NEXT) offset = get_last_viewable_item() - focus; else if (wp == VK_DOWN) offset = 1; else if (wp == VK_UP) offset = -1; //if (offset) process_keydown(offset, ((HIWORD(lp) & KF_ALTDOWN) != 0), drawing_enabled, (HIWORD(lp) & KF_REPEAT) != 0); drawing_enabled = true; RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); return 0; } else if (wp == VK_SPACE) { int focus = playlist_api->activeplaylist_get_focus_item(); set_sel_single(focus, true, false, false); return 0; } else if (wp == VK_RETURN) { bool ctrl_down = 0 != (GetKeyState(VK_CONTROL) & KF_UP); int focus = playlist_api->activeplaylist_get_focus_item(); unsigned active = playlist_api->get_active_playlist(); if (ctrl_down) { if (active != -1 && focus != -1) playlist_api->queue_add_item_playlist(active, focus); } else { // playlist_api->set_playing_playlist(active); unsigned focus = playlist_api->activeplaylist_get_focus_item(); //unsigned active = playlist_api->get_active_playlist(); //playlist_api->playlist_set_playback_cursor(active, focus); playlist_api->activeplaylist_execute_default_action(focus); //static_api_ptr_t<play_control>()->play_start(play_control::track_command_settrack); } return 0; } else if (wp == VK_SHIFT) { if (!(HIWORD(lp) & KF_REPEAT)) g_shift_item_start = playlist_api->activeplaylist_get_focus_item(); } else if (wp == VK_F2) { unsigned count = g_get_cache().active_column_get_active_count(); if (count) { unsigned focus = playlist_api->activeplaylist_get_focus_item(); if (focus != pfc_infinite) { t_size i, pcount = playlist_api->activeplaylist_get_item_count(); bit_array_bittable sel(pcount); playlist_api->activeplaylist_get_selection_mask(sel); pfc::list_t<t_size> indices; indices.prealloc(32); for (i = 0; i<pcount; i++) if (sel[i]) indices.add_item(i); /*t_size start = focus, end = focus; if (sel[start] && pcount) { while (start>0 && sel[start-1]) start--; while (end<pcount-1 && sel[end+1]) end++; }*/ unsigned count = g_get_cache().active_column_get_active_count(); unsigned column; for (column = 0; column<count; column++) { if (!g_get_columns()[g_get_cache().active_column_active_to_actual(column)]->edit_field.is_empty()) { //create_inline_edit_v2(start, end-start+1, column); create_inline_edit_v2(indices, column); break; } } } } } else if (wp == VK_DELETE) { playlist_api->activeplaylist_undo_backup(); playlist_api->activeplaylist_remove_selection(); } else if (wp == VK_F3) { standard_commands::main_playlist_search(); } /*else if (vk_slash != -1 && wp == LOWORD(vk_slash)) { HWND wnd_search = m_searcher.create(wnd); on_size(); ShowWindow(wnd_search, SW_SHOWNORMAL); ; }*/ } } break; case WM_CHAR: if (!m_prevent_wm_char_processing) { //if (!(HIWORD(lp) & KF_REPEAT)) { if ((GetKeyState(VK_CONTROL) & KF_UP)) { static_api_ptr_t<playlist_manager> playlist_api; if (wp == 1) //Ctrl-A { playlist_api->activeplaylist_set_selection(bit_array_true(), bit_array_true()); return 0; } else if (wp == 26) //Ctrl-Z { playlist_api->activeplaylist_undo_restore(); return 0; } else if (wp == 25) //Ctrl-Y { playlist_api->activeplaylist_redo_restore(); return 0; } else if (wp == 24) //Ctrl-X { playlist_utils::cut(); return 0; } else if (wp == 3) //Ctrl-C { playlist_utils::copy(); return 0; } else if (wp == 6) //Ctrl-F { standard_commands::main_playlist_search(); return 0; } else if (wp == 22) //Ctrl-V { playlist_utils::paste(wnd); return 0; } } } } break; case WM_KEYUP: if (process_keydown(msg, lp, wp, true)) return 0; break; case WM_SYSKEYUP: if (process_keydown(msg, lp, wp, true)) return 0; break; case WM_SYSKEYDOWN: { uie::window_ptr p_this = this; if (m_prevent_wm_char_processing = process_keydown(msg, lp, wp, true)) return 0; } break; case WM_LBUTTONDOWN: { if (0 && g_tooltip) { MSG message; memset(&message, 0, sizeof(MSG)); message.hwnd = wnd; message.message = msg; message.wParam = wp; message.lParam = lp; uSendMessage(g_tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message); } bool b_was_focused = GetFocus() == wnd; if (!b_was_focused) m_no_next_edit = true; //#ifdef INLINE_EDIT exit_inline_edit(); // g_no_next_edit = false; //#endif dragged = false; SetFocus(wnd); SetCapture(wnd); static_api_ptr_t<playlist_manager> playlist_api; g_drag_lmb = true; int focus = playlist_api->activeplaylist_get_focus_item(); drag_start_lmb.x = GET_X_LPARAM(lp); drag_start_lmb.y = GET_Y_LPARAM(lp); int item_height = get_item_height(); int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp)); // int idx = ((GET_Y_LPARAM(lp) -get_header_height()) / item_height) + scroll_item_offset; // if( idx >= 0 && idx <playlist_api->activeplaylist_get_item_count() && GET_X_LPARAM(lp) < g_playlist_entries.get_total_width_actual()) if (idx >= 0) { // playlist_oper * playlist_api = playlist_api; // playlist_api->set_playback_cursor(idx); //#ifdef INLINE_EDIT m_prev_sel = (playlist_api->activeplaylist_is_item_selected(idx) && !m_wnd_edit && (playlist_api->activeplaylist_get_selection_count(2) == 1)); //#endif if (!is_visible(idx)) SendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); if (wp & MK_CONTROL && wp & MK_SHIFT) { playlist_api->activeplaylist_move_selection(idx - focus); dragged = true; drag_type = 0; } else if (wp & MK_SHIFT) { drag_type = 2; dragitem = idx, dragstartitem = idx; int n = (cfg_alternative_sel ? focus : g_shift_item_start), t = idx; bool focus_sel = playlist_api->activeplaylist_is_item_selected(focus); set_sel_range(n, t, (cfg_alternative_sel != 0), (cfg_alternative_sel ? !focus_sel : false)); playlist_api->activeplaylist_set_focus_item(idx); dragged = true; } else if (wp & MK_CONTROL) { /* drag_type = 2; dragitem = idx,dragstartitem=idx; set_sel_single(idx, false, true, false); dragged = true;*/ } else if (playlist_api->activeplaylist_is_item_selected(idx)) { drag_type = 1; dragitem = idx, dragstartitem = idx; playlist_api->activeplaylist_undo_backup(); playlist_api->activeplaylist_set_focus_item(idx); dragged = false; } else { drag_type = 2; dragitem = idx, dragstartitem = idx;//item irrelevant actually; set_sel_single(idx, false, true, true); /* bit_array_bittable mask(playlist_api->activeplaylist_get_item_count()); // playlist_api->activeplaylist_is_item_selected_mask(mask); int n, t = playlist_api->activeplaylist_get_item_count(); for (n = 0;n <t;n++) { if (n==idx) mask.set(n, true); else mask.set(n, false); } console::info("crap"); playlist_api->set_sel_mask(mask); playlist_api->activeplaylist_set_focus_item(idx);*/ dragged = false; } } else { // console::info("wow"); // bit_array_bittable mask(playlist_api->activeplaylist_get_item_count()); playlist_api->activeplaylist_set_selection(bit_array_true(), bit_array_false()); dragged = true; drag_type = 0; } } break; case WM_RBUTTONUP: m_no_next_edit = false; break; case WM_MBUTTONUP: { m_no_next_edit = false; unsigned idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp)); playlist_mclick_actions::run(cfg_playlist_middle_action, idx != -1, idx); } break; case WM_LBUTTONUP: { if (0 && g_tooltip) { MSG message; memset(&message, 0, sizeof(MSG)); message.hwnd = wnd; message.message = msg; message.wParam = wp; message.lParam = lp; uSendMessage(g_tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message); } ReleaseCapture(); g_drag_lmb = false; int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), true); //((GET_Y_LPARAM(lp) -get_header_height()) / get_item_height()) + scroll_item_offset; static_api_ptr_t<playlist_manager> playlist_api; if (!dragged) { if (wp & MK_CONTROL) { // int idx_down = hittest_item(drag_start_lmb.x, drag_start_lmb.y); if (idx >= 0) set_sel_single(idx, true, true, false); } else { // int item_height = get_item_height(); // int idx = ((GET_Y_LPARAM(lp) - get_header_height()) / item_height) + scroll_item_offset; if (idx >= 0 /*&& idx < playlist_api->activeplaylist_get_item_count() && (GET_X_LPARAM(lp) < g_playlist_entries.get_total_width_actual())*/) { if (!m_no_next_edit && cfg_inline_edit && playlist_api->activeplaylist_is_item_selected(idx) && m_prev_sel /*&& !dragged*/) { //if (m_no_next_edit && GetCapture() == wnd) ReleaseCapture(); { exit_inline_edit(); if (main_window::config_get_inline_metafield_edit_mode() != main_window::mode_disabled) { m_edit_index = idx; long width; m_edit_column = hittest_column(GET_X_LPARAM(lp), width); if (m_edit_column >= 0 && !g_get_columns()[g_get_cache().active_column_active_to_actual(m_edit_column)]->edit_field.is_empty()) { m_edit_timer = (SetTimer(wnd, EDIT_TIMER_ID, GetDoubleClickTime(), 0) != 0); } } } } int focus = playlist_api->activeplaylist_get_focus_item(); set_sel_single(focus, false, false, true); } } } dragged = true; drag_type = 0; dragstartitem = 0; dragitem = 0; //#ifdef INLINE_EDIT m_no_next_edit = false; //#endif } break; case WM_MOUSEMOVE: { if (0 && g_tooltip) { MSG message; memset(&message, 0, sizeof(MSG)); message.hwnd = wnd; message.message = msg; message.wParam = wp; message.lParam = lp; uSendMessage(g_tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message); } const unsigned cx_drag = (unsigned)abs(GetSystemMetrics(SM_CXDRAG)); const unsigned cy_drag = (unsigned)abs(GetSystemMetrics(SM_CYDRAG)); if (!g_dragging && ((g_dragging1 && wp & MK_RBUTTON && (abs(drag_start.x - GET_X_LPARAM(lp)) > cx_drag || abs(drag_start.y - GET_Y_LPARAM(lp)) > cy_drag)) || (g_drag_lmb && (wp & MK_LBUTTON) && (wp & MK_CONTROL) && (abs(drag_start_lmb.x - GET_X_LPARAM(lp)) > 3 || abs(drag_start_lmb.y - GET_Y_LPARAM(lp)) > 3)))) { static_api_ptr_t<playlist_manager> playlist_api; metadb_handle_list data; playlist_api->activeplaylist_get_selected_items(data); if (data.get_count() > 0) { static_api_ptr_t<playlist_incoming_item_filter> incoming_api; IDataObject * pDataObject = incoming_api->create_dataobject(data); if (pDataObject) { //RegisterClipboardFormat(_T("foo_ui_columns"); if (g_tooltip) { DestroyWindow(g_tooltip); g_tooltip = 0; last_idx = -1; last_column = -1; } DWORD blah; { pfc::com_ptr_t<IDropSource_playlist> p_IDropSource_playlist = new IDropSource_playlist(this); DoDragDrop(pDataObject, p_IDropSource_playlist.get_ptr(), DROPEFFECT_COPY, &blah); } pDataObject->Release(); } } data.remove_all(); g_dragging = false; g_dragging1 = false; g_drag_lmb = false; if (wp & MK_LBUTTON) { dragged = true; drag_type = 0; dragstartitem = 0; dragitem = 0; } } if (cfg_tooltip && (GET_Y_LPARAM(lp) > get_header_height())) { int item_height = get_item_height(); int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp)); long cx; int column = hittest_column(GET_X_LPARAM(lp), cx); // unsigned act_col = g_cache.active_column_active_to_actual(column); if (column >= 0 && idx >= 0) { if (last_idx != (idx) || last_column != column) { if (!cfg_tooltips_clipped || is_item_clipped(idx, column)) { pfc::string8 src; g_cache.active_get_display_name(idx, column, src); pfc::string8 temp; titleformat_compiler::remove_color_marks(src, temp); temp.replace_char(9, 0x20); CreateToolTip(temp); } else { DestroyWindow(g_tooltip); g_tooltip = 0; last_idx = -1; last_column = -1; } POINT a; a.x = cx + 3; a.y = (idx - scroll_item_offset) * item_height + get_header_height(); ClientToScreen(wnd_playlist, &a); tooltip.top = a.y; tooltip.bottom = a.y + item_height; tooltip.left = a.x; tooltip.right = a.x + get_column_width(column); } last_idx = idx; last_column = column; } else { DestroyWindow(g_tooltip); g_tooltip = 0; last_idx = -1; last_column = -1; } } if (drag_type && (wp & MK_LBUTTON) && !(GetKeyState(VK_SHIFT) & KF_UP) && !(GetKeyState(VK_CONTROL) & KF_UP)) { RECT rc; get_playlist_rect(&rc); static_api_ptr_t<playlist_manager> playlist_api; int total = playlist_api->activeplaylist_get_item_count(); int item_height = get_item_height(); int valid_idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), false); int idx = hittest_item_no_scroll(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), false); // (GET_Y_LPARAM(lp) - get_header_height()) / (item_height); int items_count = ((rc.bottom - rc.top) / item_height) + 1; if ((idx + scroll_item_offset) != dragitem || GET_Y_LPARAM(lp) < get_header_height()) //(idx + scroll_item_offset) < playlist_api->activeplaylist_get_item_count() { if (idx >= items_count - 1) { bool need_redrawing = false; int focus = playlist_api->activeplaylist_get_focus_item(); SCROLLINFO si; memset(&si, 0, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_POS; GetScrollInfo(wnd_playlist, SB_VERT, &si); int old_offset = si.nPos; si.nPos += 3; scroll_item_offset = SetScrollInfo(wnd_playlist, SB_VERT, &si, true); if (old_offset != scroll_item_offset) need_redrawing = true; int t = scroll_item_offset + items_count - 2; //n=dragitem, if (t > total) t = total - 1; if (t != dragitem) { drawing_enabled = false; if (drag_type == 1) playlist_api->activeplaylist_move_selection((rc.bottom - rc.top) / item_height + scroll_item_offset - focus - 1); else if (drag_type == 2) { set_sel_range(dragstartitem, t, false); playlist_api->activeplaylist_set_focus_item(t); } dragitem = t; drawing_enabled = true; need_redrawing = true; } if (need_redrawing) RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); } else if (idx < 0 || GET_Y_LPARAM(lp) < get_header_height() || GET_Y_LPARAM(lp) < 0) { int focus = playlist_api->activeplaylist_get_focus_item(); bool need_redrawing = false; SCROLLINFO si; memset(&si, 0, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_POS; GetScrollInfo(wnd_playlist, SB_VERT, &si); int old_offset = si.nPos; si.nPos -= 3; scroll_item_offset = SetScrollInfo(wnd_playlist, SB_VERT, &si, true); if (old_offset != scroll_item_offset) need_redrawing = true; if (dragitem != scroll_item_offset) { drawing_enabled = false; if (drag_type == 1) playlist_api->activeplaylist_move_selection(scroll_item_offset - focus); else if (drag_type == 2) { set_sel_range(dragstartitem, scroll_item_offset, false); playlist_api->activeplaylist_set_focus_item(scroll_item_offset); RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); } dragitem = scroll_item_offset; drawing_enabled = true; need_redrawing = true; } if (need_redrawing) RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); } else { int focus = playlist_api->activeplaylist_get_focus_item(); if (drag_type == 1) playlist_api->activeplaylist_move_selection(idx + scroll_item_offset - focus); else if (drag_type == 2) { if (valid_idx >= 0) { drawing_enabled = false; set_sel_range(dragstartitem, valid_idx, false); playlist_api->activeplaylist_set_focus_item(valid_idx); drawing_enabled = true; RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); } } dragitem = valid_idx; dragged = true; } } } else if (!(wp & MK_LBUTTON)) drag_type = 0; } break; case WM_LBUTTONDBLCLK: { int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), true); if (idx >= 0) { //#ifdef INLINE_EDIT exit_inline_edit(); m_no_next_edit = true; //#endif //if (!is_visible(idx)) uSendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0),0); #if 0 // DEATH's code case WM_LBUTTONDBLCLK: { int idx = item_from_point((short)HIWORD(lp)); if (idx >= 0 && idx<(int)m_api->activeplaylist_get_item_count()) { m_api->activeplaylist_set_focus_item(idx); static_api_ptr_t<play_control>()->play_start(play_control::TRACK_COMMAND_SETTRACK); } } return 0; #endif static_api_ptr_t<playlist_manager> playlist_api; //unsigned active = playlist_api->get_active_playlist(); // playlist_api->set_playing_playlist(active); //playlist_api->playlist_set_playback_cursor(active, idx); //playlist_api->queue_flush(); unsigned focus = playlist_api->activeplaylist_get_focus_item(); playlist_api->activeplaylist_execute_default_action(focus); } else if (cfg_playlist_double.get_value().m_command != pfc::guid_null) { mainmenu_commands::g_execute(cfg_playlist_double.get_value().m_command); } dragged = true; } break; case WM_RBUTTONDOWN: { if (wnd_playlist) SetFocus(wnd_playlist); g_dragging1 = true; drag_start.x = GET_X_LPARAM(lp); drag_start.y = GET_Y_LPARAM(lp); static_api_ptr_t<playlist_manager> playlist_api; // int item_height = get_item_height(); // int idx = ((GET_Y_LPARAM(lp) - get_header_height()) / item_height) + scroll_item_offset; int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), true); if (idx != -1 && !is_visible(idx)) SendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); if (idx >= 0 /*&& idx < playlist_api->activeplaylist_get_item_count() && (GET_X_LPARAM(lp) < g_playlist_entries.get_total_width_actual())*/) { if (!playlist_api->activeplaylist_is_item_selected(idx) && !(GetKeyState(VK_CONTROL) & KF_UP)) { set_sel_single(idx, false, false, true); } playlist_api->activeplaylist_set_focus_item(idx); } } break; case WM_MOUSEWHEEL: {//GET_WHEEL_DELTA_WPARAM exit_inline_edit(); if (1 || (wp & MK_CONTROL)) { LONG_PTR style = GetWindowLongPtr(wnd_playlist, GWL_STYLE); if (!(style & WS_VSCROLL) || ((wp & MK_CONTROL) && (style & WS_HSCROLL))) { if ((style & WS_HSCROLL)) { SCROLLINFO si; memset(&si, 0, sizeof(SCROLLINFO)); si.fMask = SIF_PAGE; si.cbSize = sizeof(SCROLLINFO); GetScrollInfo(wnd, SB_HORZ, &si); int new_pos = horizontal_offset; int old_pos = horizontal_offset; unsigned scroll_lines = GetNumScrollLines(); int zDelta = short(HIWORD(wp)); if (scroll_lines == -1) { scroll_lines = si.nPage > 1 ? si.nPage - 1 : 1; } else scroll_lines *= 3; int delta = MulDiv(zDelta, scroll_lines, 120); if (!si.nPage) si.nPage++; if (delta < 0 && delta*-1 > si.nPage) { delta = si.nPage*-1; if (delta >1) delta--; } else if (delta > 0 && delta > si.nPage) { delta = si.nPage; if (delta >1) delta--; } scroll(scroll_horizontally, scroll_position_delta, -delta); } return 1; } } SCROLLINFO si; memset(&si, 0, sizeof(SCROLLINFO)); si.fMask = SIF_PAGE; si.cbSize = sizeof(SCROLLINFO); GetScrollInfo(wnd, SB_VERT, &si); int new_pos = scroll_item_offset; int old_pos = scroll_item_offset; unsigned scroll_lines = GetNumScrollLines(); int zDelta = short(HIWORD(wp)); if (scroll_lines == -1) { scroll_lines = si.nPage > 1 ? si.nPage - 1 : 1; } int delta = MulDiv(zDelta, scroll_lines, 120); if (!si.nPage) si.nPage++; if (delta < 0 && delta*-1 > si.nPage) { delta = si.nPage*-1; if (delta >1) delta--; } else if (delta > 0 && delta > si.nPage) { delta = si.nPage; if (delta >1) delta--; } scroll(scroll_vertically, scroll_position_delta, -delta); } return 1; case WM_VSCROLL: { exit_inline_edit(); scroll(scroll_vertically, scroll_sb, LOWORD(wp)); } return 0; case WM_HSCROLL: { exit_inline_edit(); scroll(scroll_horizontally, scroll_sb, LOWORD(wp)); } return 0; case WM_MENUSELECT: { if (HIWORD(wp) & MF_POPUP) { m_status_override.release(); } else { if (g_main_menu_a.is_valid() || g_main_menu_b.is_valid()) { unsigned id = LOWORD(wp); bool set = false; pfc::string8 desc; if (g_main_menu_a.is_valid() && id < MENU_B_BASE) { set = g_main_menu_a->get_description(id - MENU_A_BASE, desc); } else if (g_main_menu_b.is_valid()) { contextmenu_node * node = g_main_menu_b->find_by_id(id - MENU_B_BASE); if (node) set = node->get_description(desc); } service_ptr_t<ui_status_text_override> p_status_override; if (set) { get_host()->override_status_text_create(p_status_override); if (p_status_override.is_valid()) { p_status_override->override_text(desc); } } m_status_override = p_status_override; } } } break; case WM_CONTEXTMENU: { uie::window_ptr p_this_temp = this; if ((HWND)wp == wnd_header) { POINT pt = { (short)LOWORD(lp), (short)HIWORD(lp) }; POINT temp; temp.x = pt.x; temp.y = pt.y; ScreenToClient(wnd_header, &temp); HDHITTESTINFO hittest; hittest.pt.x = temp.x; hittest.pt.y = temp.y; uSendMessage(wnd_header, HDM_HITTEST, 0, (LPARAM)&hittest); enum { IDM_ASC = 1, IDM_DES = 2, IDM_SEL_ASC, IDM_SEL_DES, IDM_AUTOSIZE, IDM_PREFS, IDM_EDIT_COLUMN, IDM_CUSTOM_BASE }; HMENU menu = CreatePopupMenu(); HMENU selection_menu = CreatePopupMenu(); if (!(hittest.flags & HHT_NOWHERE)) { uAppendMenu(menu, (MF_STRING), IDM_ASC, "&Sort ascending"); uAppendMenu(menu, (MF_STRING), IDM_DES, "Sort &descending"); uAppendMenu(selection_menu, (MF_STRING), IDM_SEL_ASC, "Sort a&scending"); uAppendMenu(selection_menu, (MF_STRING), IDM_SEL_DES, "Sort d&escending"); uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)selection_menu, "Se&lection"); uAppendMenu(menu, (MF_SEPARATOR), 0, ""); uAppendMenu(menu, (MF_STRING), IDM_EDIT_COLUMN, "&Edit this column"); uAppendMenu(menu, (MF_SEPARATOR), 0, ""); uAppendMenu(menu, (MF_STRING | (cfg_nohscroll ? MF_CHECKED : MF_UNCHECKED)), IDM_AUTOSIZE, "&Auto-sizing columns"); uAppendMenu(menu, (MF_STRING), IDM_PREFS, "&Preferences"); uAppendMenu(menu, (MF_SEPARATOR), 0, ""); pfc::string8 playlist_name; static_api_ptr_t<playlist_manager> playlist_api; playlist_api->activeplaylist_get_name(playlist_name); pfc::string8_fast_aggressive filter, name; int s, e = columns.get_count(); for (s = 0; s<e; s++) { bool add = false; switch (columns[s]->filter_type) { case FILTER_NONE: { add = true; break; } case FILTER_SHOW: { if (wildcard_helper::test(playlist_name, columns[s]->filter, true)) { add = true; /* g_columns.get_string(s, name, STRING_NAME); uAppendMenu(menu,MF_STRING|MF_CHECKED,IDM_CUSTOM_BASE+s,name);*/ } } break; case FILTER_HIDE: { if (!wildcard_helper::test(playlist_name, columns[s]->filter, true)) { add = true; /* g_columns.get_string(s, name, STRING_NAME); uAppendMenu(menu,MF_STRING|MF_CHECKED,IDM_CUSTOM_BASE+s,name);*/ } } break; } if (add) { uAppendMenu(menu, MF_STRING | (columns[s]->show ? MF_CHECKED : MF_UNCHECKED), IDM_CUSTOM_BASE + s, columns[s]->name); } } } else { uAppendMenu(menu, (MF_STRING | (cfg_nohscroll ? MF_CHECKED : MF_UNCHECKED)), IDM_AUTOSIZE, "&Auto-sizing columns"); uAppendMenu(menu, (MF_STRING), IDM_PREFS, "&Preferences"); } menu_helpers::win32_auto_mnemonics(menu); int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, wnd, 0); DestroyMenu(menu); if (cmd == IDM_ASC) { g_set_sort(hittest.iItem, false); } else if (cmd == IDM_DES) { g_set_sort(hittest.iItem, true); } else if (cmd == IDM_SEL_ASC) { g_set_sort(hittest.iItem, false, true); } else if (cmd == IDM_SEL_DES) { g_set_sort(hittest.iItem, true, true); } else if (cmd == IDM_EDIT_COLUMN) { g_set_tab("Columns"); cfg_cur_prefs_col = g_cache.active_column_active_to_actual(hittest.iItem); //get_idx static_api_ptr_t<ui_control>()->show_preferences(columns::config_get_playlist_view_guid()); } else if (cmd == IDM_AUTOSIZE) { cfg_nohscroll = cfg_nohscroll == 0; update_all_windows(); pvt::ng_playlist_view_t::g_on_autosize_change(); } else if (cmd == IDM_PREFS) { static_api_ptr_t<ui_control>()->show_preferences(columns::config_get_main_guid()); } else if (cmd >= IDM_CUSTOM_BASE) { if (t_size(cmd - IDM_CUSTOM_BASE) < columns.get_count()) { columns[cmd - IDM_CUSTOM_BASE]->show = !columns[cmd - IDM_CUSTOM_BASE]->show; //g_columns //if (!cfg_nohscroll) g_save_columns(); //g_cache.flush_all(); g_reset_columns(); update_all_windows(); pvt::ng_playlist_view_t::g_on_columns_change(); } } return 0; } else if ((HWND)wp == wnd) { //DWORD mp = GetMessagePos(); POINT px, pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) }; static_api_ptr_t<playlist_manager> playlist_api; if (playlist_api->activeplaylist_get_selection_count(1) > 0 && 1) { if (pt.x == -1 && pt.y == -1) { int focus = playlist_api->activeplaylist_get_focus_item(); unsigned last = get_last_viewable_item(); if (focus == -1 || focus < scroll_item_offset || focus > last) { px.x = 0; px.y = 0; } else { RECT rc; get_playlist_rect(&rc); px.x = 0; unsigned item_height = get_item_height(); px.y = (focus - scroll_item_offset)*(item_height)+item_height / 2 + rc.top; } pt = px; MapWindowPoints(wnd, HWND_DESKTOP, &pt, 1); } else { px = pt; ScreenToClient(wnd, &px); //int idx = hittest_item(px.x, px.y); //if (!is_visible(idx)) // SendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0),0); } // int idx = hittest_item(px.x, px.y); enum { ID_PLAY = 1, ID_CUT, ID_COPY, ID_PASTE, ID_SELECTION, ID_CUSTOM_BASE = 0x8000 }; HMENU menu = CreatePopupMenu();//LoadMenu(core_api::get_my_instance(),MAKEINTRESOURCE(IDR_TREEPOPUP)); service_ptr_t<mainmenu_manager> p_manager_selection; service_ptr_t<contextmenu_manager> p_manager_context; p_manager_selection = standard_api_create_t<mainmenu_manager>(); contextmenu_manager::g_create(p_manager_context); if (p_manager_selection.is_valid()) { p_manager_selection->instantiate(mainmenu_groups::edit_part2_selection); p_manager_selection->generate_menu_win32(menu, ID_SELECTION, ID_CUSTOM_BASE - ID_SELECTION, standard_config_objects::query_show_keyboard_shortcuts_in_menus() ? contextmenu_manager::FLAG_SHOW_SHORTCUTS : 0); if (GetMenuItemCount(menu) > 0) uAppendMenu(menu, MF_SEPARATOR, 0, ""); } AppendMenu(menu, MF_STRING, ID_CUT, L"Cut"); AppendMenu(menu, MF_STRING, ID_COPY, L"Copy"); if (playlist_utils::check_clipboard()) AppendMenu(menu, MF_STRING, ID_PASTE, L"Paste"); AppendMenu(menu, MF_SEPARATOR, 0, NULL); if (p_manager_context.is_valid()) { const keyboard_shortcut_manager::shortcut_type shortcuts[] = { keyboard_shortcut_manager::TYPE_CONTEXT_PLAYLIST, keyboard_shortcut_manager::TYPE_CONTEXT }; p_manager_context->set_shortcut_preference(shortcuts, tabsize(shortcuts)); p_manager_context->init_context_playlist(standard_config_objects::query_show_keyboard_shortcuts_in_menus() ? contextmenu_manager::FLAG_SHOW_SHORTCUTS : 0); p_manager_context->win32_build_menu(menu, ID_CUSTOM_BASE, -1); } menu_helpers::win32_auto_mnemonics(menu); MENU_A_BASE = ID_SELECTION; MENU_B_BASE = ID_CUSTOM_BASE; g_main_menu_a = p_manager_selection; g_main_menu_b = p_manager_context; int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, wnd, 0); if (m_status_override.is_valid()) { m_status_override.release(); } DestroyMenu(menu); if (cmd) { if (cmd == ID_CUT) { playlist_utils::cut(); } else if (cmd == ID_COPY) { playlist_utils::copy(); } else if (cmd == ID_PASTE) { playlist_utils::paste(wnd); } else if (cmd >= ID_SELECTION && cmd<ID_CUSTOM_BASE) { if (p_manager_selection.is_valid()) { p_manager_selection->execute_command(cmd - ID_SELECTION); } } else if (cmd >= ID_CUSTOM_BASE) { if (p_manager_context.is_valid()) { p_manager_context->execute_by_id(cmd - ID_CUSTOM_BASE); } } } g_main_menu_a.release(); g_main_menu_b.release(); } // contextmenu_manager::win32_run_menu_context_playlist(wnd, 0, config_object::g_get_data_bool_simple(standard_config_objects::bool_show_keyboard_shortcuts_in_menus, true) ? contextmenu_manager::FLAG_SHOW_SHORTCUTS : 0); } } return 0; //#ifdef INLINE_EDIT case WM_PARENTNOTIFY: { if (wp == WM_DESTROY) { if (m_wnd_edit && (HWND)lp == m_wnd_edit) m_wnd_edit = 0; } } break; case MSG_KILL_INLINE_EDIT: exit_inline_edit(); return 0; #if 1 case WM_COMMAND: switch (wp) { case (EN_CHANGE << 16) | 667: { m_edit_changed = true; } break; } break; #endif case WM_TIMER: { if (wp == EDIT_TIMER_ID) { create_inline_edit_v2(m_edit_index, m_edit_column); if (m_edit_timer) { KillTimer(wnd_playlist, EDIT_TIMER_ID); m_edit_timer = false; } return 0; } } break; //#endif case WM_NOTIFY: switch (((LPNMHDR)lp)->idFrom) { case ID_PLAYLIST_TOOLTIP: switch (((LPNMHDR)lp)->code) { case TTN_SHOW: RECT rc, rc_tt; rc = tooltip; GetWindowRect(g_tooltip, &rc_tt); int offset = MulDiv(get_item_height() - rc_tt.bottom + rc_tt.top, 1, 2); rc.top += offset; SetWindowPos(g_tooltip, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); return TRUE; } break; case 5001: switch (((LPNMHDR)lp)->code) { case HDN_BEGINTRACKA: case HDN_BEGINTRACKW: { return (cfg_nohscroll ? TRUE : FALSE); } case HDN_ENDDRAG: { if (((LPNMHEADERA)lp)->iButton == 0) { if (((LPNMHEADERA)lp)->pitem && (((LPNMHEADERA)lp)->pitem->mask & HDI_ORDER)) { int from = ((LPNMHEADERA)lp)->iItem; int to = ((LPNMHEADERA)lp)->pitem->iOrder; if (to >= 0 && from != to) { int act_from = g_cache.active_column_active_to_actual(from), act_to = g_cache.active_column_active_to_actual(to); columns.move(act_from, act_to); //if (!cfg_nohscroll) g_save_columns(); g_reset_columns(); update_all_windows(); pvt::ng_playlist_view_t::g_on_columns_change(); } } else { } } return (TRUE); } case HDN_DIVIDERDBLCLICK: if (!cfg_nohscroll) { static_api_ptr_t<playlist_manager> playlist_api; HDC hdc; hdc = GetDC(wnd_playlist); int size; pfc::string8 text; SelectObject(hdc, g_font); int w = 0, n, t = playlist_api->activeplaylist_get_item_count(); for (n = 0; n<t; n++) { // playlist_api->format_title(n, text, g_playlist_entries.get_display_spec(((LPNMHEADER)lp)->iItem), NULL); g_cache.active_get_display_name(n, ((LPNMHEADER)lp)->iItem, text); size = ui_helpers::get_text_width_color(hdc, text, text.length()); if (size > w) w = size; } // g_playlist_entries.get_column(((LPNMHEADER)lp)->iItem)->_set_width(w+5); columns[g_cache.active_column_active_to_actual(((LPNMHEADER)lp)->iItem)]->width = w + 15; ReleaseDC(wnd_playlist, hdc); update_all_windows(); g_save_columns(); pvt::ng_playlist_view_t::g_on_column_widths_change(); } return 0; case HDN_ITEMCLICK: { bool des = false; static_api_ptr_t<playlist_manager> playlist_api; unsigned col; bool descending; bool sorted = g_cache.active_get_playlist_sort(col, &descending); if (sorted && col == ((LPNMHEADER)lp)->iItem) des = !descending; g_set_sort(((LPNMHEADER)lp)->iItem, des /*, playlist_api->activeplaylist_get_selection_count(1) && cfg_sortsel != 0*/); } break; case HDN_ITEMCHANGED: { if (!cfg_nohscroll) { if (((LPNMHEADER)lp)->pitem->mask & HDI_WIDTH) columns[g_cache.active_column_active_to_actual(((LPNMHEADER)lp)->iItem)]->width = ((LPNMHEADER)lp)->pitem->cxy; update_all_windows(wnd_header); g_save_columns(); pvt::ng_playlist_view_t::g_on_column_widths_change(); } } break; } break; } } return uDefWindowProc(wnd, msg, wp, lp); }
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(); } }
bool ShellDirectory::fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA* pw32fdata, BY_HANDLE_FILE_INFORMATION* pbhfi, bool do_access) { CONTEXT("ShellDirectory::fill_w32fdata_shell()"); bool bhfi_valid = false; if (do_access && !( (attribs&SFGAO_FILESYSTEM) && SUCCEEDED( SHGetDataFromIDList(_folder, pidl, SHGDFIL_FINDDATA, pw32fdata, sizeof(WIN32_FIND_DATA))) )) { WIN32_FILE_ATTRIBUTE_DATA fad; IDataObject* pDataObj; STGMEDIUM medium = {0, {0}, 0}; FORMATETC fmt = {g_Globals._cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; HRESULT hr = _folder->GetUIObjectOf(0, 1, &pidl, IID_IDataObject, 0, (LPVOID*)&pDataObj); if (SUCCEEDED(hr)) { hr = pDataObj->GetData(&fmt, &medium); pDataObj->Release(); if (SUCCEEDED(hr)) { LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal)); if (path) { // fill with drive names "C:", ... assert(_tcslen(path) < GlobalSize(medium.UNION_MEMBER(hGlobal))); _tcscpy(pw32fdata->cFileName, path); UINT sem_org = SetErrorMode(SEM_FAILCRITICALERRORS); if (GetFileAttributesEx(path, GetFileExInfoStandard, &fad)) { pw32fdata->dwFileAttributes = fad.dwFileAttributes; pw32fdata->ftCreationTime = fad.ftCreationTime; pw32fdata->ftLastAccessTime = fad.ftLastAccessTime; pw32fdata->ftLastWriteTime = fad.ftLastWriteTime; if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // copy file size pw32fdata->nFileSizeLow = fad.nFileSizeLow; pw32fdata->nFileSizeHigh = fad.nFileSizeHigh; } else { // ignore FILE_ATTRIBUTE_HIDDEN attribute of NTFS drives - this would hide those drives in ShellBrowser if (pw32fdata->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { if (path[1]==':' && path[2]=='\\' && !path[3]) // Is it a drive path? pw32fdata->dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN; } } } HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (hFile != INVALID_HANDLE_VALUE) { if (GetFileInformationByHandle(hFile, pbhfi)) bhfi_valid = true; CloseHandle(hFile); } SetErrorMode(sem_org); GlobalUnlock(medium.UNION_MEMBER(hGlobal)); GlobalFree(medium.UNION_MEMBER(hGlobal)); } } } } if (!do_access || !(attribs&SFGAO_FILESYSTEM)) // Archiv files should not be displayed as folders in explorer view. if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER)) pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; if (attribs & SFGAO_READONLY) pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; if (attribs & SFGAO_COMPRESSED) pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_COMPRESSED; return bhfi_valid; }