Текущий архив: 2005.12.11;
Скачать: CL | DM;
ВнизПолучение иконок типов файлов - как сделать быстрее? Найти похожие ветки
← →
kami © (2005-11-26 14:52) [0]Написал такой код:
var
Strings:TStringList;
const
StepLoadIcons=30;
procedure TfmMain.FillExtList;
const
Flag=SHGFI_ICON or SHGFI_LARGEICON or SHGFI_USEFILEATTRIBUTES;
var
r:TRegistry;
i:integer;
s:string;
fi: _SHFILEINFOA;
begin
Strings.BeginUpdate;
r:=TRegistry.Create(KEY_READ);
r.RootKey:=HKey_Classes_Root;
r.OpenKey("",false);
r.GetKeyNames(Strings);
r.Free;
i:=Strings.Count-1;
While Strings.Strings[i][1]<>"." do
begin
Strings.Delete(i); // удалили все до последнего зарегистрированного
dec(i); // типа файла
end;
fmLoading.ProgressBar1.Max:=Strings.Count-1;
fmLoading.ProgressBar1.Step:=StepLoadIcons;
i:=1;// потому что нулевой элемент имеет имя "/"
CoInitialize(nil);
repeat
s:=Strings.Strings[i];
if (i mod StepLoadIcons)=0 then
begin // если убрать отображение прогресса, то загрузка становится всего на 3-5 с. быстрее
fmLoading.lbDescription.Caption:="Загружается : иконка "+s;
fmLoading.ProgressBar1.StepIt;
Application.ProcessMessages;
end;
ZeroMemory(@fi, SizeOf(fi));
SHGetFileInfo(@s[1], FILE_ATTRIBUTE_NORMAL, fi, SizeOf(fi),Flag);// тормоза возникают (скорее всего) именно здесь
ImageList_AddIcon(ImageList.Handle,fi.hIcon);
inc(i);
until i=Strings.Count;
Strings.EndUpdate;
CoUninitialize;
end;
Этот код выполняется при запуске программы, и отрабатывает секунд за 20-30 при первом запуске, при последующих (наверное, из-за буферизации) секунд за 7-10. Получение всех зарегистрированных расширений из реестра проходит почти моментально, а вот само получение иконок - очень долго, на мой взгляд.
Как можно ускорить этот процесс? Может, есть другие ф-и получения иконки без наличия самого файла, которые будут работать быстрее? (нужна пара "расширение файла"-"иконка") ?
← →
Eraser © (2005-11-26 15:16) [1]
> kami © (26.11.05 14:52)
Всё гораздо проще )
Получить список всех зарегистрированых иконок можно такilIcons.Handle := SHGetFileInfo(PChar(""),
, где
0,
FileInfo,
SizeOf(TSHFileInfo),
SHGFI_ADDOVERLAYS or
SHGFI_ICON or SHGFI_SMALLICON or
SHGFI_SYSICONINDEX);
ilIcons: TImageList.
не забудь предварительно поставитьilIcons.ShareImages := true;<.CODE>
Чтобы потом получить доступ к нужной иконки - просто бери её индекс и обращайся к нужному элементу в ilIcons.SHGetFileInfo(PChar(ListItem.Caption),
FILE_ATTRIBUTE_NORMAL,
FileInfo,
SizeOf(TSHFileInfo),
SHGFI_USEFILEATTRIBUTES or
SHGFI_ICON or SHGFI_SMALLICON or
SHGFI_TYPENAME or
SHGFI_SYSICONINDEX or SHGFI_ADDOVERLAYS);
...
ListItem.ImageIndex := FileInfo.iIcon;
← →
Lamer@fools.ua © (2005-11-26 15:26) [2]Попробуйте убрать SHGFI_USEFILEATTRIBUTES из
const Flag
.
← →
kami © (2005-11-26 15:34) [3]Eraser © (26.11.05 15:16) [1]
Точно !!!
Давно пытался найти, как получается системный ImageList, но не нашел, где.
Спасибо!!!
← →
kami © (2005-11-26 19:16) [4]Eraser © (26.11.05 15:16) [1]
Поясни, пожалуйста.
Ну, получение хендла системного ImageList понятно (хотя, несовсем, но разберусь).
Сейчас сделал тестовую программку, так она выдает, что изначально в ImageList всего 4 иконки, а потом, при загрузке иконки конкретного типа файла, она добавляется в список. То есть, в системном списке иконок у них нет фиксированного индекса, по которому в любой момент можно было бы обратиться, и более того - даже наличие иконки необязательно ? Как-то это ... нездОрово. -\
← →
Eraser © (2005-11-26 20:15) [5]
> kami © (26.11.05 19:16) [4]
> То есть, в системном списке иконок у них нет фиксированного
> индекса, по которому в любой момент можно было бы обратиться,
> и более того - даже наличие иконки необязательно ?
Фиксированный индекс как раз таки есть, но только он будет различный для различных процессов.Once you have a handle to a system image list, you can use the Image List API to manipulate it like any other image list. Because system image lists are created on a per-process basis, you should treat them as read-only objects. Writing to a system image list may overwrite or delete one of the system images, making it unavailable or incorrect for the remainder of the process.
Читай MSDN.
← →
Eraser © (2005-11-26 20:25) [6]
> kami © (26.11.05 19:16) [4]
Более того, ты можешь добавлять свои иконки в системный список иконок своего процесса.
← →
kami © (2005-11-26 21:26) [7]Eraser © (26.11.05 20:15) [5]
будет различный для различных процессов
Именно это я и имел ввиду, что нельзя однозначно сказать, что иконка №5 будет (допустим) от .folder, все зависит от того, когда ее затребуют.
> Читай MSDN.
Сперва именно его и читаю. Вот что упустил - так это что системный список именно создается для конкретного процесса (думал, что он один на всех). Каюсь, грешен :)
Видимо, придется смириться, ну да ладно - уже все переделал под эту особенность :)
Спасибо.
Страницы: 1 вся ветка
Текущий архив: 2005.12.11;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.04 c