Доброго времени суток. Имеется необходимость получить иконки файлов. Суть такая:
Имеются некие файлы-архивы, с нестандартной структурой файла. Проще говоря, я пишу приложение-архиватор для своего типа файлов.
Все бы ничего, но хотелось бы скрасить некрасивый голый список файлов иконками (как в проводнике). Соответственно я начал изучать этот вопрос, как же получить иконку по расширению файла.
Например: у меня установлен AIMP и все поддерживаемые AIMP'ом файлы отображаются его иконками. EXE, DLL, BAT, CMD и др - системными иконками.
Можно поискать готовые решения в виде ShellListBox, ShellListView и т.д., но они не подойдут, как минимум потому, что файлы, которыми я заполняю список не распакованы, они находятся в файле-архиве.
Соответственно функции по типу ExtractIcon (ссылка на docs.microsoft.com) и др. не подходят, файла-то нет. Я нашел одно решение - поиск иконок по реестру. В принципе это работает, но далеко не так, как хотелось бы...
Информация в реестре почему-то порой не соответствует указанным мною параметрам. Например, в реестре у меня иконки подгружаются из файла VLC.exe. Изначально так оно и было, пока я не сменил их на AIMP, в проводнике это привело к нужному результату (иконки сменились), а вот в реестре до сих пор отображается VLC, соответственно, когда я ищу иконку по расширению .mp3, я нахожу иконку VLC, хотя настройки ассоциации формата .mp3 явно указывают на AIMP.
Так же, в реестре порой можно наткнуться на отсутствие необходимых ключей и значений, в таком случае я реализовал подгрузку иконки (Unknown. т.е, когда проводник не распознал формат файла и показывает просто белый файл). В итоге у меня половина проверенных мною форматов шла (Unknown).
Собственно вопрос: В какую сторону копать для решения данной проблемы? (Решения "только для FireMonkey" не подойдут, ибо нужны именно WinAPI-решения).
Код получения иконки по формату файла: (не самое лучшее решение, это очевидно).
Спойлер
function GetIcon(aExtension: string): HICON;
begin
if reg = nil then
reg := TRegistry.Create();
reg.RootKey := HKEY_CLASSES_ROOT;
var iconPath: TArray<string> := [];
if (aExtension = '') then
begin
reg.OpenKey('Folder\DefaultIcon', false);
iconPath := reg.ReadString('').Split([',']);
reg.CloseKey();
FreeAndNil(reg);
Exit(ExtractIcon(0, PChar(iconPath[0]), StrToInt(iconPath[1])));
end
else
begin
reg.OpenKey(aExtension, false);
var iconRef: string := reg.ReadString('');
reg.CloseKey();
reg.OpenKey(iconRef, false);
if (reg.KeyExists('DefaultIcon')) then
begin
reg.OpenKey('DefaultIcon', false);
iconPath := reg.ReadString('').Split([',']);
if (iconPath[0].StartsWith('"') or iconPath[0].EndsWith('"')) then
iconPath[0] := iconPath[0].Trim(['"']);
reg.CloseKey();
FreeAndNil(reg);
Exit(ExtractIcon(0, PChar(iconPath[0]), StrToInt(iconPath[1])));
end;
end;
reg.CloseKey();
reg.OpenKey('Unknown\DefaultIcon', false);
iconPath := reg.ReadString('').Split([',']);
Result := ExtractIcon(0, PChar(iconPath[0]), StrToInt(iconPath[1]));
end;
Прикрепляю небольшой пример использования этой функции.
Вопрос
Dmitry_4501
Доброго времени суток. Имеется необходимость получить иконки файлов. Суть такая:
Имеются некие файлы-архивы, с нестандартной структурой файла. Проще говоря, я пишу приложение-архиватор для своего типа файлов.
Все бы ничего, но хотелось бы скрасить некрасивый голый список файлов иконками (как в проводнике). Соответственно я начал изучать этот вопрос, как же получить иконку по расширению файла.
Например: у меня установлен AIMP и все поддерживаемые AIMP'ом файлы отображаются его иконками. EXE, DLL, BAT, CMD и др - системными иконками.
Можно поискать готовые решения в виде ShellListBox, ShellListView и т.д., но они не подойдут, как минимум потому, что файлы, которыми я заполняю список не распакованы, они находятся в файле-архиве.
Соответственно функции по типу ExtractIcon (ссылка на docs.microsoft.com) и др. не подходят, файла-то нет. Я нашел одно решение - поиск иконок по реестру. В принципе это работает, но далеко не так, как хотелось бы...
Информация в реестре почему-то порой не соответствует указанным мною параметрам. Например, в реестре у меня иконки подгружаются из файла VLC.exe. Изначально так оно и было, пока я не сменил их на AIMP, в проводнике это привело к нужному результату (иконки сменились), а вот в реестре до сих пор отображается VLC, соответственно, когда я ищу иконку по расширению .mp3, я нахожу иконку VLC, хотя настройки ассоциации формата .mp3 явно указывают на AIMP.
Так же, в реестре порой можно наткнуться на отсутствие необходимых ключей и значений, в таком случае я реализовал подгрузку иконки (Unknown. т.е, когда проводник не распознал формат файла и показывает просто белый файл). В итоге у меня половина проверенных мною форматов шла (Unknown).
Собственно вопрос: В какую сторону копать для решения данной проблемы? (Решения "только для FireMonkey" не подойдут, ибо нужны именно WinAPI-решения).
Код получения иконки по формату файла: (не самое лучшее решение, это очевидно).
Прикрепляю небольшой пример использования этой функции.
Project1.zip
Ссылка на комментарий
8 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.