Цель данного урока - создание и навигация по двухуровневой ФС.
В корне виртуальной файловой системы располагаются 2 объекта:
- [Default Dir] - Это значение настраиваемо, по умолчанию получаем с помощью SHGetFolderPath(CSIDL_DESKTOP)
- [Shell Folders] - Здесь "файлы" - пункты, получаемые с помощью WinAPI-функции SHGetFolderPath
Функция GetFindDataW теперь возвращает два набора данных:
- Файловые объекты верхнего уровня ("[Shell Folders]" и "[Default Dir]"), когды мы в корне панели.
- Файловые объекты "сборник Shell-каталогов", когда мы в виртуальной папке "[Shell Folders]".
- Для упрощения подпапки именуем по названию CSIDL_-констант (см. SDK-файл ShlObj.h), в поле PluginPanelItem::Description для информативности помещаем путь к каталогу, соответствующему этой константе.
- в функции GetOpenPanelInfoW указать OpenPanelInfo::CurDir отличным от пустой строки
- в функции SetDirectoryW вернуть TRUE
- Выход в корень панели из виртуальных подкаталогов (например, с помощью Ctrl-\) - плагин в SetDirectoryInfo::Dir получает значение "\" (как вариант - SetDirectoryInfo::Dir=nullptr). В этом случае просто выставляем признак верхнего уровня (__TopLevel=true) и возвращаем управление в Far Manager. Надо заметить, что Far Manager сам корректно обрабатывает ситуацию с Ctrl-\, если мы в корне панели (панель плагина закрывается).
- Выход на предыдущий уровень в виртуальной файловой системе - плагин в SetDirectoryInfo::Dir получает значение "..". Действия аналогичные выходу в корень панели, т.к. в нашей панели только 2 уровня вложенности.
- Переход в дефолтовый каталог - плагин в SetDirectoryInfo::Dir получает значение "[Default Dir]". Здесь как обычно закрываем панель, указав путь к каталогу по умолчанию.
- Переход в "сборник Shell-каталогов" - плагин в SetDirectoryInfo::Dir получает значение "[Shell Folders]". Выставим признак покидания верхнего уровня (__TopLevel=false) и передадим управление в Far Manager.
- Переход в любой из каталогов из "сборник Shell-каталогов" - плагин в SetDirectoryInfo::Dir получает значение "CSIDL_что-то-там" (см. массив desktop.cpp::CSIDL[]), признак верхнего уровня сброшен (__TopLevel=false). Ищем в массиве аналогичное имя, с помощью функции SHGetFolderPath() получаем реальный путь и даем сигнал на закрытие панели с указанием реального пути.