Как получить PIDL IShellFolder

Perl:

sub is_palindrome($)
{
  $s = lc(shift); # ignore case
  $s =~ s/\W+//g; # consider only letters, digits, and '_'
  $s eq reverse $s;
}

Это игнорирует регистр и разделяет неалфавитно-цифровые символы (это локаль - и unicode-нейтральный).

7
задан Ian Boyd 17 August 2014 в 22:33
поделиться

2 ответа

Я обнаружил, что вы можете запросить IShellFolder для его IPersistFolder2, который имеет GetCurFolder (), который возвращает его абсолютный PIDL. Затем я мог бы просто использовать IShellFolder для рабочего стола для CompareIDs (), чтобы определить, равны ли они. Я нашел это в общих чертах, глядя на SHGetIDListFromObject . Я не мог просто использовать эту функцию, потому что это Vista, а мне нужна совместимость с XP.

Вот набросок того, как это работает (при условии, что у вас есть ifolder_desktop и ifolder_other, которые являются указателями IShellFolder. Pidl - простой помощник, который гарантирует, что IDLIST будут освобождены должным образом):

CComQIPtr<IPersistFolder2> ipf2_desktop(ifolder_desktop);
CComQIPtr<IPersistFolder2> ipf2_folder(ifolder_other);

Pidl pidl_desktop, pidl_folder;
VERIFY(SUCCEEDED(ipf2_desktop->GetCurFolder(pidl_desktop)));
VERIFY(SUCCEEDED(ipf2_folder->GetCurFolder(pidl_folder)));

HRESULT hr = ifolder_desktop->CompareIDs(NULL, pidl_desktop, pidl_folder);
pCmdUI->Enable(SUCCEEDED(hr) && HRESULT_CODE(hr) != 0);

На случай, если кому-то интересен мой простой класс Pidl:

class Pidl
{
public:
    // create empty
    Pidl() : m_pidl(NULL) { }

    // create one of specified size
    explicit Pidl(size_t size) : m_pidl(Pidl_Create(size)) {}

    // create a copy of a given PIDL
    explicit Pidl(const ITEMIDLIST * pidl) : m_pidl(Pidl_Copy(pidl)) {}

    // create an absolute PIDL from a parent + child
    Pidl(const ITEMIDLIST_ABSOLUTE * pParent, const ITEMIDLIST_RELATIVE * pChild) : m_pidl(Pidl_Concatenate(pParent, pChild)) { }

    // return our PIDL for general use (but retain ownership of it)
    operator const ITEMIDLIST * () { return m_pidl; }

    // return a pointer to our pointer, for use in functions that assign to a PIDL
    operator ITEMIDLIST ** () 
    {
        free();
        return &m_pidl; 
    }

    // release ownership of our PIDL
    ITEMIDLIST * release() 
    { 
        ITEMIDLIST * pidl = m_pidl;
        m_pidl = NULL;
        return pidl;
    }

    void free()
    {
        if (m_pidl)
            //Pidl_Free(m_pidl);
            ILFree(m_pidl);
    }

    // automatically free our pidl (if we have one)
    ~Pidl()
    {
        free();
    }

private:
    ITEMIDLIST * m_pidl;
};
6
ответ дан 6 December 2019 в 10:00
поделиться

Ответ Мордачай может быть правильным, но для меня этот запрос не имеет смысла по двум направлениям:

  1. Я не верю, что есть опубликованный документ, в котором говорится, что IShellFolder может иметь только одного родителя . К любой конкретной папке оболочки может быть несколько способов. панель управления доступна через Мой компьютер, через меню Пуск и в любом месте файловой системы, которую вы создаете точка соединения с ней. Похоже, первоначальное намерение команд оболочки заключалось в том, что при наличии экземпляра IShellFolder не должно иметь значения для внешних пользователей , какое его произвольное местоположение произошло.

  2. Кроме того, любое приложение, которое создает экземпляр IShellFolder , безусловно, сделал это ОТ ЗНАНИЯ PIDL. Если ваше приложение заботится о пути к IShellFolder, оно уже ИМЕЕТ эту информацию. Как ты его потерял? (И почему команда оболочки должна добавлять метод, помогающий приложениям отслеживать свои собственные данные?)

1
ответ дан 6 December 2019 в 10:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: