Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2005.12.11;
Скачать: [xml.tar.bz2];

Вниз

Получение иконок типов файлов - как сделать быстрее?   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.038 c
1-1131637337
GrayFace
2005-11-10 18:42
2005.12.11
Получение содержимого регистров при исключении.


14-1132330160
x.pro
2005-11-18 19:09
2005.12.11
С днем студента!


2-1132850108
serko
2005-11-24 19:35
2005.12.11
Combobox


2-1132550552
Mamur
2005-11-21 08:22
2005.12.11
Обращение из папки которой запускается


14-1132406727
Пока ещё студент
2005-11-19 16:25
2005.12.11
Курсач





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский