示例#1
0
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));
}
示例#2
0
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;
}
示例#3
0
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));
}
示例#4
0
ShellFolder Entry::get_shell_folder() const
{
	return ShellFolder(create_absolute_pidl());
}