2016-11-03 4 views
0

В настоящее время я работаю над настольным приложением Windows, использующим VB.net, где я хотел бы иметь интерфейс для прямого доступа к файлам и папкам, то есть пользователю не нужно открывать диалоговое окно браузера файлов для выбора файлов.VB.net или Windows API: как узнать, какие значки использует файловый проводник?

Мой файловый браузер должен напоминать оригинальный проводник файлов Windows, по крайней мере, тем, что он использует те же значки для наиболее распространенных мест. Например, я хотел бы включить папку «Избранное» с соответствующим значком (обратите внимание, что это НЕ папка избранного IE, а папка, которая появляется при вводе shell:links в адресную строку файлового проводника).

Моя проблема заключается в выборе значка. До сих пор я написал класс-оболочку для некоторых функций Windows API, в частности SHGetKnownFolderPath и SHGetFileInfo. Мой подход заключается в следующем:

1) Используйте SHGetKnownFolderPath, чтобы получить полный путь к соответствующему местоположению (что зависит от версии Windows и локализации). Эта часть работает, как и ожидалось. Например, в моей системе (W7 Pro x64) SHGetKnownFolderPath возвращает «C: \ Users \ Administrator \ Links» при запросе с соответствующим rfid.

2) Используйте SHGetFileInfo для получения значка, который Windows рассматривает значок по умолчанию для пути, полученного в 1). Эта часть технически также работает, , но неправильный значок возвращается - неправильно в том смысле, что это другой значок, чем Windows-проводник для использования в том же месте.

Я пробовал это с четырьмя различными местоположениями (MyLibraries, MyFavorites (Links), MyComputer, MyNetwork). Значок для MyLibraries был ожидаемым, остальные три полностью отличались от значков, которые использует Windows Explorer.

Так что я получил некоторые вопросов:

1) Есть ли способ, чтобы определить, какие иконки используются с помощью стандартного файлового проводника Windows, для некоторых папок, например, «Избранное» (C: \ Users \ Administrator \ Links на моей машине)? Меня бы интересовало общее решение (т. Е. Решение, которое работает для всех местоположений described here).

2) Если такого пути нет, я узнаю номер (индекс) всех значков, интересующих shell32.dll (на самом деле их осталось всего несколько). Могу ли я быть уверенным, что эти индексы не изменятся в будущем?

3) Согласно this document, я должен позвонить CoInitialize перед использованием SHGetFileInfo. Я считаю, что .NET framework автоматически делает это для основного потока, прежде чем запускать его, и, таким образом, еще не сделал этого сам по себе (разработка приложения только началась, и на данный момент есть только один поток).

Я думаю, что недостающий звонок CoInitialize не может быть причиной появления «неправильных» значков. Если я ошибаюсь, пожалуйста, дайте мне знать.

Потенциальным решением может быть использование языка .NET или родного Windows API/SDK. Пока есть какой-то способ (даже очень сложный) использовать решение из VB.net, я буду этому доволен.

+1

Вы должны задать один вопрос за сообщение. – Plutonix

+1

См. [SHGetStockIconInfo] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762205 (v = vs.85) .aspx). Это может помочь. –

+0

@KenWhite Эта ссылка очень интересная, я еще не знал об этой функции. С другой стороны, нет никакой гарантии, что проводник Windows-файлов использует значки из этого списка, а в списке отсутствуют значки, которые используются проводником файлов Windows (например, значок «Избранное»). Тем не менее, я мог бы предположить переход на этот набор значков, если нет другого (прямого) решения моей проблемы. – Binarus

ответ

3

Проводник использует 2 способа обнаружения значка любого объекта, файла или папки.

1) вызов IShellFolder.GetUIObjectOf (IExtractIconA/W) и работать с IExtractIcon.

2) запрос IShellFolder.QueryInterface (IShellIcon) и вызов IShellIcon.GetIconOf.

Вы можете сделать то же самое.

+0

Принято как ответ и плюс 1, но до сих пор ничего не известно о интерфейсах и интерфейсе COM. У меня очень сложное время с реализацией этого решения. Кажется, что я не могу узнать, как использовать указатель на интерфейс, чтобы получить сам интерфейс в VB.net. Я отправлю еще один вопрос об этом. – Binarus