PDA

Просмотр полной версии : Название интерфейса к Explorer bar "Folders"?



AiK
17.03.2004, 23:51
Хочу использовать в собственной программе Explorer bar "Folders".
Возможно это из Shell'a, т.к. используется и в NT Explore'e и в IE.
Возможно и в Outlook Express он же используется, только pidlRoot другой. Беда в том, что понятия не имею как эта штуковина грамотно называется. По-ламерски: нужна функциональность SHBrowseForFolder, но не в отдельном диалоге, а так как в IE см. View->Explorer bar->Folders

Andy
18.03.2004, 00:53
Если я правильно все понял, то есть 2 предложения:
1. Использовать мой собственный ActiveX контрол, который является функциональной заменой SHBrowseForFolder() (более мощной). Загрузить можно с моего сайта http://shell-controls.narod.ru . Там же про него написано более подробно (автоматизация, connection points). Компонент пока тестируется и поэтому бесплатный.
2. Писать все самому. Писать придется много, но зато можно сделать по-своему. Все перечислять очень долго, но самые основные моменты выделю:

Установить для дерева Shell Image List
Инициализировать дерево с pidl Desktop'a (например). Получить его можно API SHGetSpecialFolderLocation() (CLSID == CSIDL_DESKTOP)
Отобразить в дереве все десктоповские дочерние элементы с помощью методов IShellFolder::EnumObjects и Enum'a.
При раскрытии какого-либо итема повторять предыдущий пункт

Если нужен второй способ, то посоветую статью Леона Финкера на www.codeproject.com (раздел Shell Programming). Очень рекомендую! Там правда на WTL (но лучше её нет).

AiK
18.03.2004, 01:36
Первый способ не годится. Есть много на то причин и первая из них заключается в твоём "пока" :)
Второй способ конечно хорош, но
а) я запарился с извлечением иконок и
б) EnumObjects выдаёт папки вперемешку с файлами. А это не есть хорошо. А сортировать вручную неохота.
в) Это дерево - не самоцель, хотя и был бы весьма удобен в проекте.

Т.е. я этот способ отбросил, после того как понял, что, скажем, за неделю по вечерам его написать и оттестировать на _разных_ платформах не получится. Поэтому очень хочется третий способ - заюзать родной для системы элемент.

Andy
18.03.2004, 10:46
Дело в том, что Windows применяет именно 2-ой способ :). По крайней мере в Проводнике все заполняется таким способом. Так что легких путей нет.

а) я запарился с извлечением иконок
Это самое простое. Привожу пример из кода своего ActiveX компонента.


SHFILEINFO sfi;
LPITEMIDLIST pidlDesktop;

// get desktop's PIDL
SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP,&pidlDesktop);
// get imagelist & set images
m_hShellImageList = (HIMAGELIST)SHGetFileInfo((LPTSTR)pidlDesktop,
0,&sfi,sizeof(SHFILEINFO),SHGFI_PIDL | SHGFI_SMALLICON
| SHGFI_SYSICONINDEX);

TreeView_SetImageList(m_hShellTree,m_hShellImageLi st,TVSIL_NORMAL);

Все! Теперь картинки установлены.

EnumObjects выдаёт папки вперемешку с файлами. А это не есть хорошо.
Используй там константу SHCONTF_FOLDERS.

Вообще повторюсь про вышеуказанную статью - лучше ее нет.

Если не гемороиться, то остается только использовать чью-то ActiveX. Кроме моей есть несколько таких разработок - но у них куча недостатков (размер ~500кБ, так как написаны на Delphi, высокая цена и проч.)

AiK
18.03.2004, 12:44
Дело в том, что Windows применяет именно 2-ой способ . По крайней мере в Проводнике все заполняется таким способом
Терзают меня смутные сомнения, что уже в IE применяется 3-й способ :)

Используй там константу SHCONTF_FOLDERS.
Я немного криво выразился. Мне нужны и файлы и папки. Но сгруппированные: сначала папки, потом файлы. У меня они почему-то идут вперемешку, тупо отсортированные по алфавиту.

Если не гемороиться, то остается только использовать чью-то ActiveX
Не годидзе. Я тогда уж SHBrowseForFolder обойдусь :)

Andy
18.03.2004, 13:35
Терзают меня смутные сомнения, что уже в IE применяется 3-й способ
Если это так, то в любом случае он недокументирован, к сожалению. ListView - да он реализован. IShellFolder::CreateViewObject и т.д.

У меня они почему-то идут вперемешку, тупо отсортированные по алфавиту.
Да, сортировку надо делать самому...

Я тогда уж SHBrowseForFolder обойдусь
Если не нужна дополнительная функциональность - хороший вариант :)

<offtopic>
Почему-то уведомления об ответах не приходят, хотя вроде всё настроил... :(
</offtopic>

AiK
18.03.2004, 14:03
Если это так, то в любом случае он недокументирован, к сожалению
Ну, GUID уже установил, попробую что-нибудь нарыть...


Почему-то уведомления об ответах не приходят, хотя вроде всё настроил
Может в Минске цензура не успевает проворачиваться? :) Если всё настроил - должны
ходить. По крайней мере ты первый, кто жалуется.

Andy
18.03.2004, 14:42
Ну, GUID уже установил, попробую что-нибудь нарыть...
Если что найдешь - сообщай (хотябы тот же самый GUID). Это дело интересное :)

AiK
18.03.2004, 15:18
хотябы тот же самый GUID
Это как раз просто. Вот этот код вызовет папку Folders в эксплорере:


<html>
<body>
<object id="WebBrowser1" classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2" height="0" width="0"></object>
<script>
WebBrowser1.ShowBrowserbar("{EFA24E64-B078-11d0-89E4-00C04FC9E26E}", true);
</script>
</body>
</html>


Первый параметр ShowBrowserbar и есть искомый CLSID. Только пердуперждаю: у меня после первого запуска этого скрипта напрочь перестал этот бар работать. Пришлось восстанавливать IE.

Hawk
18.03.2004, 15:29
По моему тут вы все усложняете =) начиная от дисков FindFirstFile, FindNextFile и SHGetFileInfo практически все что надо делают. Для отделения файлов от папок проще сделать два прохода - в первом добавить все файлы у который атрибуты - папка, а во втором наоборот.

Andy
18.03.2004, 16:11
По моему тут вы все усложняете =) начиная от дисков FindFirstFile, FindNextFile и SHGetFileInfo практически все что надо делают.
Понимаешь, тут много недостатков. Например виртуальные папки (вроде My Documents/Control Panel) так получить нельзя...

Вот этот код вызовет папку Folders в эксплорере:
Интересная вещь! :) Надо с этим поковыряться. В Platform SDK нашел на эту тему немного материала...

Hawk
19.03.2004, 10:57
Кстати по IShellFolder и т.п. в MSDN более чем подробно все описано

Hawk
19.03.2004, 11:15
Простите за длинну, но тут неплохой примерчик - (http://groups.google.com.ru/groups?hl=ru&lr=&ie=UTF-8&oe=UTF-8&threadm=bu1mbk%24b3%241%40news01.intel.com&rnum=1&prev=/groups%3Fq%3DSHGetFileInfo%2B%2522My%2Bcomputer%25 22%26hl%3Dru%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3Dbu1mbk%2524b3%25241%2540news01.intel.co m%26rnum%3D1)

AiK
19.03.2004, 12:55
Hawk, сипасибо за пример, озябательно изучу :)

по IShellFolder и т.п.
Через него и "и т.п." и делал. Но, есть кое-какие траблы. Во-первых извлечение иконок какое-то нетривиальное получается. То, что прекрасно работает на win2K напрочь перестаёт работать под win98. А во-вторых, когда я запрашиваю сначала папки, а потом файлы при помощи SHCONTF_FOLDERS и SHCONTF_NONFOLDERS, то диски мне в обоих случаях возвращают... т.е. похоже действительно с атрибутами возиться придётся.

Eugie
19.03.2004, 16:45
AiK, ты кажется на Delphi пишешь? Посмотри в 7-ке на закладке Samples компонент ShellTreeView (там еще куча всего). Исходники в демосах в папке ShellControls. Я юзал сей тры_вью, ничего плохого не заметил...
Звиняюсь, вынужден убежать :)

AiK
19.03.2004, 21:18
Eugie, совет хороший, но плохой :) Во-первых, у меня нет 7-ки. А во-вторых хотелось бы иметь решение, не зависящее от языка реализации.

Hawk
22.03.2004, 12:09
Aik
глянь rsdn (http://www.rsdn.ru/summary/246.xml) там по Shell-у много чего хорошего написано

Romeo
25.03.2004, 11:47
Люди, сори, что у меня не хватило времени прочитать всё, что написано на эту тему, но сразу скажу, что могу помочь очень многим. Дело в том, что пару месяцев назад у меня возникла задача создась ActiveX элемент управления, напоминающий стандартный виндовский OpenFileDialog. К данному моменту компонент реализован на 95%. Помучаться мне пришлось несказанно, уж поверьте наслово. Так что если вонзникают конкрентные проблемы - обращайтесь.

AiK
25.03.2004, 11:54
Пока что другие проблемы навалились, так что временно мне не до фолдеров :)
Hawk, Акжана я читал чуть ли не в том же 2001м году :), а остальное и в msdn имеется.