Re[3]: Shell Windows
От: Юрий Жмеренецкий ICQ 380412032
Дата: 25.04.08 14:54
Оценка: 7 (2)
Здравствуйте, white_znake, Вы писали:

_>Вот вопрос — у меня лежит папка MyFolder в MyDocuments (C:\Documents and Settings\user1\My Documents\MyFolder)

_>1. Я получаю piidl на папку MyFolder через IShellFolder::ParseDisplayName()
_>2. Получаю piidlParent на папку My Computer через SHGetFolderLocation()
_>3. Получаю IShellFolder* на папку My Computer через SHBindToParent()
_>4. После использую SHCreateShellItem для создания папки с piidl в качестве дочерней по отношению к piidlParent

_>Судя по возвращаемым значениям все ок, но MyFolder не отображается в My Computer

_>Что я делаю не так?

Все так, только этот код и не должен создавать дочерний элемент. IShellItem это обертка над существующим элементом. Все методы IShellItem вызывают соответствующие методы родительского ISellFolder.

Самый "важный" интерфейс, который обязательно нужно реализовать — это IShellFolder. Он пердставляет собой "виртуальную" папку в tree view проводника
Некоторые методы:
BindToObject — Получить дочернюю папку
CompareIDs — Сравнивает два элемента. Предикат сортировки.
CreateViewObject — Создает то, что отображается в правой панели. Это не обязательно список файлов — может быть все что угодно. Кроме того, с помощью этой функции explorer запрашивает вспомогательные интерфейсы, например IDropTarget/IDropSource.
EnumObjects — Используется для перечисления дочерних объектов(в первую очередь папок)
GetAttributesOf — Возвращает атрибуты дочернего элемента.
GetUIObjectOf — В какой-то мере аналог CreateViewObject, но для tree view. Возвращает интерфейсы поддерживаемые объектом-"папка". В первую очередь это IContextMenu.

За то, что отображается в правой панели проводника отвечает IShellView. Можно отобразить хоть html'ку, хоть внедренный диалог с контролами.
Если необходим обычный список объектов(файлов), то варианты:
— "IShellView руками": list ctrl, + обработка WM_*/LVN_* сообщений. Все как в обычном приложении.
— Использовать готовую реализацию, т.н. DefView. Для его создания предназначена SHCreateShellFolderView, + необходимо реализовать IShellFolderViewCB. В результате получится правая панель, которая ни чем не отличается от стандартного проводника. Готовое контекстное меню, icon/report/* view, некоторая поддержка drag'n'drop'a, и т.п. Серьезный минус этого вариант — практически полное отсутствие документации. Т.е. работать будет, но если захочется какой-нибудь кастомизации, то это будет очень проблематично реализовать.

Дальше. Для универсальной идентификации объектов и навигации по всему(древовидному) namespace'у в explorer'e применяются т.н. PIDL'ы.
Каждый объект имеет свой уникальный(в пределах родителя) идентификатор "переменной длины" представленный структурой SHITEMID. Набор таких структур однозначно определяют расположение элемента в оболочке(по аналогии с путями для файлов).

В структуре SHITEMID фиксированным является только поле "размер", после которого идут приватные данные. Приватные — потому что только namespace extension(NSE), которое создало pidl, знает как их интерпретировать. Там может находится все что угодно — строки, указатели на внутренние структуры и т.п.(поэтому создание PIDL'ов вне NSE бессмысленно)

Таким образом, еще одной обязательной (если конечно NSE состоит не из одного корневого элемента) деталью является формат SHITEMID. Т.к. explorer совершенно не знает его форматa, то для извлечения данных он использует IShellFolder::GetAttributesOf, IShellFolder::CompareIDs(сравнивать умеет только NSE, но не explorer) и некоторые другие функции.

Существуют два вида NSE:
* rooted — в tree view отображается только его корень и дочерние элементы(невозможно перейти, например к FS).
* все остальные — корень находится где-то в иерархии оболочки. Может присутствовать в единственном экземпляре(Control Panel/My Network Places), либо в нескольких.
Любое NSE можно привязать к расширению файла (например zip-folders).

Реализация ISellFolder должна находится в COM-dll, которая регистрируется в реестре(нюансы описаны в MSDN).
Выше я писал — в Platform SDK есть пример RegView — это "IShellView руками", а MSF использует DefView. Хоть RegView далеко не эталон NSE, но основные моменты там есть.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.