Почему PIDL для панели управления будет отличаться?
Я вижу, что нужно сделать это , чтобы сравнить PIDLs: IShellFolder::CompareIDs().
В частности, я пытаюсь определить, является ли данный абсолютный PIDL (или относительный) Pidl панели управления. Однако на практике я получаю два Pidl, которые ishellfolder:: CompareIDs() утверждает, что они не равны, когда они должны быть (глядя на GetDisplayName() для каждого, я вижу, что мы действительно смотрим на панель управления).В принципе, я получаю абсолютный PIDL на панели управления:
PIDL iidControlPanel = nullptr;
SHGetSpecialFolderLocation(hwnd, CSIDL_CONTROLS, &iidControlPanel);
И затем сравнение входящего перечисляемого объекта оболочки, например (см. здесь для контекста-в двух словах это смотрит на результаты перечисления пространства имен оболочки рабочего стола внутри CMFCShellTreeCtrl):
bool bIsControlPanel = CompareAbsolutePIDLs(iidControlPanel, pItem->pidlFQ);
Для справки, вот функция сравнения:
bool CompareAbsolutePIDLs(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
{
CComPtr<IShellFolder> ishDesk;
SHGetDesktopFolder(&ishDesk);
HRESULT hr = ishDesk->CompareIDs(SHCIDS_CANONICALONLY, pidl1, pidl2);
return SUCCEEDED(hr) && HRESULT_CODE(hr) == 0;
}
В отладчике я вижу, что GetDisplayName () для каждого возвращает:
"::{26EE0668-A00A-44D7-9371-BEB064C98683}"
"::{26EE0668-A00A-44D7-9371-BEB064C98683}"
Здесь вы можете увидеть шестнадцатеричный дамп PIDLs:
1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *0c* 00
1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *00* 00
В базовые PIDL также являются двоичными идентичными, за исключением предпоследнего значения (00 против 0c). Я в настоящее время в недоумении, почему они отличаются, или что я могу сделать, чтобы решить эту проблему?!
Вопросы
- Есть ли другой способ получить PIDL элемента управления it таким образом, чтобы не включать этот кажущийся ложным дополнительный нулевой байт?
- С другой стороны, есть ли лучший способ получить PIDL элемента перечисления (есть ли что-то недостаточное в том, что CMFCShellTreeCtrol получает абсолютный PIDL таким образом, что он не может включить последний нулевой байт?)
- Есть ли способ получить панель управления в виде относительного PIDL, а затем сравнить ее с относительным перечислением PIDL (которое у меня также есть)?
- ???
1 ответ:
Это действительно разные объекты оболочки. Вы можете передать Pidl, которые вы получили в SHGetNameFromIDList () с опцией SIGDN_NORMALDISPLAY, чтобы преобразовать их в читаемые строки. Длинный PIDL (с 0x0c) преобразуется в "все элементы панели управления", короткий-в"Панель управления".
Эта проблема началась с использования SHGetSpecialFolderLocation () для извлечения виртуальной папки для элементов управления панели управления. Отличается от объекта панели управления в корне рабочего стола. Я думаю вы должны исправить это, получив PIDL для Панели управления и игнорировать виртуальную папку. Один из способов сделать это-с помощью ILCloneFirst преобразовать виртуальную папку в корневой объект:
PITEMID_CHILD controlPanel = ILCloneFirst(iidControlPanel);
Или вы можете жестко закодировать CLSID панели управления,":: {26EE0668-A00A-44D7-9371-BEB064C98683}", и преобразовать его в PIDL с помощью SHParseDisplayName().