void ShellBrowser::jump_to(LPCITEMIDLIST pidl) { Entry* entry = NULL; if (!_cur_dir) _cur_dir = static_cast<ShellDirectory*>(_root._entry); //LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl))); // We could call read_tree() here to iterate through the hierarchy and open all folders // from _create_info._root_shell_path (_cur_dir) to _create_info._shell_path (pidl). // To make it easier we just use ILFindChild() instead. if (_cur_dir) { static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24); if (ILFindChild) { for(;;) { LPCITEMIDLIST child_pidl = (*ILFindChild)(_cur_dir->create_absolute_pidl(), pidl); if (!child_pidl || !child_pidl->mkid.cb) break; _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); entry = _cur_dir->find_entry(child_pidl); if (!entry) break; _cur_dir = static_cast<ShellDirectory*>(entry); _callback->entry_selected(entry); } } else { _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); entry = _cur_dir->find_entry(pidl); // This is not correct in the common case, but works on the desktop level. if (entry) { _cur_dir = static_cast<ShellDirectory*>(entry); _callback->entry_selected(entry); } } } // If not already called, now directly call UpdateFolderView() using pidl if (!entry) UpdateFolderView(ShellFolder(pidl)); }
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; }
void ShellBrowserChild::jump_to(LPCITEMIDLIST pidl) { ShellDirectory* dir = NULL; if (!_cur_dir) _cur_dir = _root._entry; if (_cur_dir) { static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24); if (ILFindChild) { for(;;) { LPCITEMIDLIST child_pidl = (*ILFindChild)(_cur_dir->create_absolute_pidl(), pidl); if (!child_pidl || !child_pidl->mkid.cb) break; _cur_dir->smart_scan(); dir = static_cast<ShellDirectory*>(_cur_dir->find_entry(child_pidl)); if (!dir) break; jump_to(dir); } } else { _cur_dir->smart_scan(); dir = static_cast<ShellDirectory*>(_cur_dir->find_entry(pidl)); // This is not correct in the common case, but works on the desktop level. if (dir) jump_to(dir); } } // If not already called, now directly call UpdateFolderView() using pidl. if (!dir) UpdateFolderView(ShellFolder(pidl)); }
ShellFolder Entry::get_shell_folder() const { return ShellFolder(create_absolute_pidl()); }