HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) { LPITEMIDLIST pidl; HRESULT ret; *ppv = NULL; ret = SHParseDisplayName(pszPath, pbc, &pidl, 0, NULL); if(SUCCEEDED(ret)) { ret = SHCreateItemFromIDList(pidl, riid, ppv); ILFree(pidl); } return ret; }
HRESULT CMainWindow::FindImages() { HRESULT hr = S_OK; if (m_thumbs == NULL) { // Walk the Pictures library IShellItem *pShellItemPicturesLibrary; hr = SHGetKnownFolderItem( FOLDERID_PicturesLibrary, KF_FLAG_CREATE, NULL, IID_PPV_ARGS(&pShellItemPicturesLibrary) ); if (SUCCEEDED(hr)) { INamespaceWalk *pNamespaceWalk; hr = CoCreateInstance( CLSID_NamespaceWalker, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&pNamespaceWalk) ); if (SUCCEEDED(hr)) { hr = pNamespaceWalk->Walk( pShellItemPicturesLibrary, NSWF_NONE_IMPLIES_ALL, 1, NULL ); if (SUCCEEDED(hr)) { // Retrieve the array of PIDLs gathered in the walk UINT itemCount; PIDLIST_ABSOLUTE *ppidls; hr = pNamespaceWalk->GetIDArrayResult( &itemCount, &ppidls ); if (SUCCEEDED(hr)) { // Create the uninitialized thumbnails m_thumbs = new CThumbnail[itemCount]; // Get the bitmap for each item and initialize the corresponding thumbnail object for (UINT i = 0; i < itemCount; i++) { IShellItem *pShellItem; hr = SHCreateItemFromIDList( ppidls[i], IID_PPV_ARGS(&pShellItem) ); if (SUCCEEDED(hr)) { ID2D1Bitmap *pBitmap; hr = DecodeImageFromThumbCache( pShellItem, &pBitmap ); if (SUCCEEDED(hr)) { hr = m_thumbs[m_uThumbCount].Initialize( pBitmap, m_pAnimationManager, m_pRenderTarget->GetSize().width * 0.5, m_pRenderTarget->GetSize().height * 0.5 ); if (SUCCEEDED(hr)) { m_uThumbCount++; } pBitmap->Release(); } pShellItem->Release(); } } // The calling function is responsible for freeing the PIDL array FreeIDListArray(ppidls, itemCount); if (SUCCEEDED(hr)) { // Arrange the images when they are first loaded m_pLayoutManager = new CLayoutManager(); hr = m_pLayoutManager->Initialize( m_pAnimationManager, m_pAnimationTimer, m_pTransitionLibrary, m_uThumbCount, m_thumbs ); if (SUCCEEDED(hr)) { hr = m_pLayoutManager->Resize( m_pRenderTarget->GetSize() ); } } } } pNamespaceWalk->Release(); } pShellItemPicturesLibrary->Release(); } } return hr; }
HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv) { FORMATETC fmt; STGMEDIUM medium; HRESULT ret; TRACE("%p, %x, %s, %p\n", pdtobj, dwFlags, debugstr_guid(riid), ppv); if(!pdtobj) return E_INVALIDARG; fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdtobj, &fmt, &medium); if(SUCCEEDED(ret)) { LPIDA pida = GlobalLock(medium.u.hGlobal); if((pida->cidl > 1 && !(dwFlags & DOGIF_ONLY_IF_ONE)) || pida->cidl == 1) { LPITEMIDLIST pidl; /* Get the first pidl (parent + child1) */ pidl = ILCombine((LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]), (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1])); ret = SHCreateItemFromIDList(pidl, riid, ppv); ILFree(pidl); } else { ret = E_FAIL; } GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } if(FAILED(ret) && !(dwFlags & DOGIF_NO_HDROP)) { TRACE("Attempting to fall back on CF_HDROP.\n"); fmt.cfFormat = CF_HDROP; fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdtobj, &fmt, &medium); if(SUCCEEDED(ret)) { DROPFILES *df = GlobalLock(medium.u.hGlobal); LPBYTE files = (LPBYTE)df + df->pFiles; BOOL multiple_files = FALSE; ret = E_FAIL; if(!df->fWide) { WCHAR filename[MAX_PATH]; PCSTR first_file = (PCSTR)files; if(*(files + lstrlenA(first_file) + 1) != 0) multiple_files = TRUE; if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) ) { MultiByteToWideChar(CP_ACP, 0, first_file, -1, filename, MAX_PATH); ret = SHCreateItemFromParsingName(filename, NULL, riid, ppv); } } else { PCWSTR first_file = (PCWSTR)files; if(*((PCWSTR)files + lstrlenW(first_file) + 1) != 0) multiple_files = TRUE; if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) ) ret = SHCreateItemFromParsingName(first_file, NULL, riid, ppv); } GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } } if(FAILED(ret) && !(dwFlags & DOGIF_NO_URL)) { FIXME("Failed to create item, should try CF_URL.\n"); } return ret; }
bool executeCommand(const UINT cmd, const csWStringList& files) { const csWString parallel = regReadParallel(); const DWORD parallelCount = regReadParallelCount(); const bool hasParallel = !parallel.empty() && parallelCount > 1; const DWORD flags = regReadFlags(); const bool isBatch = testFlags(flags, CMD_FLAG_BATCH); const bool isParallel = testFlags(flags, CMD_FLAG_PARALLEL) && hasParallel; const bool isUnc = testFlags(flags, CMD_FLAG_UNC) && cmd != Cmd_List; const bool isUnix = testFlags(flags, CMD_FLAG_UNIX); const csWString scriptPath = regReadScriptsPath(); const csWStringList scripts = regReadScripts(); if( cmd == Cmd_List || cmd == Cmd_ListWithPath || cmd == Cmd_ListWithPathTabular ) { int size = 0; for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { wchar_t *uncName = 0; if( isUnc && (uncName = resolveUNC(it->c_str())) != 0 ) { size += lenFN(csWString(uncName), cmd); delete[] uncName; } else { size += lenFN(*it, cmd); } } wchar_t *text = new wchar_t[size+1]; if( text == 0 ) { return false; } int pos = 0; for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { wchar_t *uncName = 0; if( isUnc && (uncName = resolveUNC(it->c_str())) != 0 ) { catFN(text, pos, csWString(uncName), cmd); delete[] uncName; } else { catFN(text, pos, *it, cmd); } } text[size] = L'\0'; if( files.size() == 1 ) { // Overwrite trailing <CR><LF> text[size-1] = text[size-2] = L'\0'; } if( isUnix ) { replace(text, size, L'\\', L'/'); } setClipboardText(text); delete[] text; return true; } else if( cmd == Cmd_CreateSymbolicLink ) { csWString symLink; IFileSaveDialog *saveDialog = NULL; HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileSaveDialog, (LPVOID*)&saveDialog); if( hr == S_OK ) { saveDialog->SetTitle(L"Create symbolic link"); const int index = files.front().lastIndexOf(L'\\'); if( index >= 0 ) { const csWString path = files.front().mid(0, index); const csWString name = files.front().mid(index+1); PIDLIST_ABSOLUTE pidl = NULL; SHParseDisplayName(path.c_str(), NULL, &pidl, 0, NULL); if( pidl != NULL ) { IShellItem *item = NULL; SHCreateItemFromIDList(pidl, IID_IShellItem, (LPVOID*)&item); if( item != NULL ) { saveDialog->SetFolder(item); item->Release(); } CoTaskMemFree(pidl); } saveDialog->SetFileName(name.c_str()); } const COMDLG_FILTERSPEC filterSpec = { L"All files", L"*.*" }; saveDialog->SetFileTypes(1, &filterSpec); const FILEOPENDIALOGOPTIONS opts = FOS_OVERWRITEPROMPT | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_CREATEPROMPT | FOS_NOREADONLYRETURN | FOS_NODEREFERENCELINKS | FOS_DONTADDTORECENT; saveDialog->SetOptions(opts); if( saveDialog->Show(NULL) == S_OK ) { IShellItem *item = NULL; if( saveDialog->GetResult(&item) == S_OK ) { wchar_t *filename = NULL; if( item->GetDisplayName(SIGDN_FILESYSPATH, &filename) == S_OK ) { symLink = filename; CoTaskMemFree(filename); } item->Release(); } } saveDialog->Release(); } if( !symLink.empty() ) { if( csFileExists(symLink.c_str()) ) { MessageBoxW(NULL, L"Symbolic link target already exists!", L"Error", MB_OK | MB_ICONERROR); return false; } const DWORD linkFlags = csIsDirectory(files.front().c_str()) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; if( CreateSymbolicLinkW(symLink.c_str(), files.front().c_str(), linkFlags) == 0 ) { const DWORD lastError = GetLastError(); csWString msg(L"ERROR(0x"); msg += csWString::number(lastError, 16); msg += L"): "; msg += formatError(lastError); MessageBoxW(NULL, msg.c_str(), L"Error", MB_OK | MB_ICONERROR); return false; } } return true; } else if( cmd == Cmd_CheckBatchProcessing ) { regWriteFlags(flags ^ CMD_FLAG_BATCH); return true; } else if( cmd == Cmd_CheckParallelExecution ) { regWriteFlags(flags ^ CMD_FLAG_PARALLEL); return true; } else if( cmd == Cmd_CheckResolveUncPaths ) { regWriteFlags(flags ^ CMD_FLAG_UNC); return true; } else if( cmd == Cmd_CheckUnixPathSeparators ) { regWriteFlags(flags ^ CMD_FLAG_UNIX); return true; } else if( Cmd_ExecuteScripts <= cmd && cmd < Cmd_ExecuteScripts+scripts.size() ) { csWString script(scriptPath + L"\\"); UINT i = 0; for(csWStringList::const_iterator it = scripts.begin(); it != scripts.end(); it++) { if( i == cmd-Cmd_ExecuteScripts ) { script += *it; break; } i++; } if( isParallel ) { csWStringList args(files); args.push_front(script); args.push_front(csWString::number(parallelCount)); ShellExecuteW(NULL, L"open", parallel.c_str(), joinFileNames(args).c_str(), NULL, SW_SHOWNORMAL); } else { // DO NOT use parallelizer if( isBatch ) { const csWString args = joinFileNames(files); ShellExecuteW(NULL, L"open", script.c_str(), args.c_str(), NULL, SW_SHOWNORMAL); } else { // NO batch processing for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { ShellExecuteW(NULL, L"open", script.c_str(), quoteFileName(*it).c_str(), NULL, SW_SHOWNORMAL); } } } return true; } return false; }
void CClassicCopyFile::GetFileInfo( IAccessible *pAcc, bool bSrc ) { long count; pAcc->get_accChildCount(&count); CComVariant children[20]; AccessibleChildren(pAcc,0,count,children,&count); wchar_t fname[_MAX_PATH]=L""; wchar_t dir[_MAX_PATH]=L""; CString size; CString date; // get the file name, directory, size and date for (int i=0;i<count;i++) { CComBSTR name; if (children[i].vt==VT_DISPATCH) { CComQIPtr<IAccessible> pChild=children[i].pdispVal; if (pChild) pChild->get_accName(CComVariant(CHILDID_SELF),&name); } else { pAcc->get_accName(children[i],&name); } switch (i) { case 2: if (wcslen(name)<_countof(fname)) wcscpy_s(fname,name); break; case 3: if (wcslen(name)<_countof(dir)) wcscpy_s(dir,name); break; case 4: size=name; break; case 5: date=name; break; } } if (bSrc) { m_FileName=fname; m_SrcSize=size; m_SrcTime=date; } else { m_DstSize=size; m_DstTime=date; } if (!fname[0] || !dir[0]) return; wchar_t fname2[_MAX_PATH]; memcpy(fname2,fname,sizeof(fname2)); *PathFindExtension(fname2)=0; int len1=Strlen(fname2); // the directory text is something like "filename (directory)". we need to parse out the real directory name int len2=Strlen(dir); if (dir[0]==0x202A) len1++; // for RTL languages the first character is some RTL marker. needs to be skipped if (len1+1>=len2 || dir[len1]!=L' ' || dir[len1+1]!=L'(' || dir[len2-1]!=L')') return; dir[len2-1]=0; // construct the full file name wchar_t path[_MAX_PATH]; _wmakepath_s(path,NULL,dir+len1+2,fname,NULL); if (!bSrc) { DWORD attrib=GetFileAttributes(path); if (attrib!=INVALID_FILE_ATTRIBUTES) { if (attrib&FILE_ATTRIBUTE_READONLY) m_bReadOnly=true; if (attrib&FILE_ATTRIBUTE_SYSTEM) m_bSystem=true; } } // get file icon HICON hIcon=NULL; PIDLIST_ABSOLUTE pidl=NULL; if (SUCCEEDED(SHParseDisplayName(path,NULL,&pidl,0,NULL)) && pidl) { int iconSize=GetSystemMetrics(SM_CXICON); HBITMAP hBitmap=NULL; CComPtr<IShellItemImageFactory> pFactory; if (SUCCEEDED(SHCreateItemFromIDList(pidl,IID_IShellItemImageFactory,(void**)&pFactory)) && pFactory) { SIZE size={iconSize,iconSize}; if (FAILED(pFactory->GetImage(size,SIIGBF_ICONONLY,&hBitmap))) hBitmap=NULL; } ILFree(pidl); if (hBitmap) { HBITMAP hMonoBitmap=CreateBitmap(iconSize,iconSize,1,1,NULL); ICONINFO info={TRUE,0,0,hMonoBitmap,hBitmap}; hIcon=CreateIconIndirect(&info); DeleteObject(hMonoBitmap); DeleteObject(hBitmap); } } if (!hIcon) return; if (bSrc) m_SrcIcon=hIcon; else m_DstIcon=hIcon; }