На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> Получить иконку с помощью IExtractIcon
    Никак не могу найти простого примера получения иконки файла с помощью IExtractIcon. Может у кого найдется примерчик?
      Обязательно IExtractIcon?
      SHGetFileInfo не подойдет?
      Недавно FAQ пополнился на этот счет: Ассоциированные с файлом иконки.
      Тут ещё что-то есть: http://stackoverflow.com/questions/3032435/delphi-shell-iextracticon-usage-and-result
        Спасибо, но нужно именно IExtractIcon

        Добавлено
        Цитата Lumen @
        Тут ещё что-то есть:

        все это видено много раз... не ясно, что с этим огрызком кода делать. :)
        Сообщение отредактировано: shershen -
          Цитата shershen @
          Может у кого найдется примерчик?


          А в чём проблема-то?

          Цитата MSDN
          To use IExtractIcon to retrieve an object's icon, do the following:
          1. Get a pointer to the IShellFolder interface of the folder that contains the object.
          2. Call IShellFolder::GetUIObjectOf with the pointer to an item identifier list (PIDL) of the object and the interface ID of IExtractIcon (IID_IExtractIcon). The folder creates an object to handle the icon extraction, and returns the object's IExtractIcon interface pointer.
          3. Call IExtractIcon::GetIconLocation to retrieve the icon's location.
          4. Call IExtractIcon::Extract to retrieve the icon's handle.


          Примеры на Delphi по работе с интерфейсами оболочки можно глянуть тут или тут. Не IExtractIcon, конечно, но принципы можно посмотреть.
            Есть вот такой странный код на билдере, работает немного кривенько, но чем богаты... может кто не сочтет за труд перевести на дельфи?

            ExpandedWrap disabled
              typedef void (WINAPI *fnILFree)(LPCITEMIDLIST);
              static fnILFree MSILFree = NULL;
               
              typedef LPITEMIDLIST (WINAPI *fnILClone)(LPCITEMIDLIST);
              static fnILClone MSILClone = NULL;
               
              typedef LPITEMIDLIST (WINAPI *fnILFindLastID)(LPCITEMIDLIST);
              static fnILFindLastID MSILFindLastID = NULL;
               
              typedef BOOL (WINAPI *fnILRemoveLastID)(LPCITEMIDLIST);
              static fnILRemoveLastID MSILRemoveLastID = NULL;
               
              typedef UINT (WINAPI *fnPrivateExtractIcons)(LPCTSTR, int, int, int, HICON*, UINT*, UINT, UINT);
              static fnPrivateExtractIcons MSPrivateExtractIcons = NULL;
               
              typedef UINT (WINAPI *fnPickIcon)(HWND, WCHAR*, UINT, int*);
              static fnPickIcon MSPickIcon = NULL;
               
              HICON EGGetIcon(WCHAR *file, UINT iconSize)
              {
                  HICON icon = NULL, tmpIcon = NULL;
               
                  IShellFolder *deskFolder = NULL;
                  IShellFolder *appObject = NULL;
                  LPITEMIDLIST pidlLocal = NULL;
                  LPITEMIDLIST pidlRelative = NULL;
                  IExtractIcon *extractIcon = NULL;
                  WCHAR iconLocation[MAX_PATH];
                  int iconIndex = 0;
                  UINT iconFlags = 0;
                  HRESULT hr;
               
                  if (MSILFree == NULL)
                      MSILFree = (fnILFree)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), (LPCSTR)155);
              //        MSILFree = (fnILFree)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "ILFree");
               
                  if (MSILClone == NULL)
                      MSILClone = (fnILClone)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), (LPCSTR)18);
              //        MSILClone = (fnILClone)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "ILClone");
               
                  if (MSILFindLastID == NULL)
                      MSILFindLastID = (fnILFindLastID)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), (LPCSTR)16);
              //        MSILFindLastID = (fnILFindLastID)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "ILFindLastID");
               
                  if (MSILRemoveLastID == NULL)
                      MSILRemoveLastID = (fnILRemoveLastID)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), (LPCSTR)17);
              //        MSILRemoveLastID = (fnILRemoveLastID)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "ILRemoveLastID");
               
                  hr = SHGetDesktopFolder(&deskFolder);
                  if (FAILED(hr))
                      return icon;
               
                  hr = deskFolder->ParseDisplayName(NULL, NULL, file, NULL, &pidlLocal, NULL);
                  if (FAILED(hr))
                  {
                      deskFolder->Release();
                      return icon;
                  }
               
                  pidlRelative = MSILClone(MSILFindLastID(pidlLocal));
                  MSILRemoveLastID(pidlLocal);
               
                  hr = deskFolder->BindToObject(pidlLocal, NULL, IID_IShellFolder, (void**)&appObject);
                  if (FAILED(hr))
                  {
                      deskFolder->Release();
                      MSILFree(pidlLocal);
                      return icon;
                  }
               
                  MSILFree(pidlLocal);
               
                  hr = appObject->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlRelative, IID_IExtractIcon, NULL,
                      (void**)&extractIcon);
                  if (FAILED(hr))
                  {
                      deskFolder->Release();
                      appObject->Release();
                      MSILFree(pidlRelative);
                      return icon;
                  }
               
                  MSILFree(pidlRelative);
               
                  hr = extractIcon->GetIconLocation(0, iconLocation, MAX_PATH, &iconIndex, &iconFlags);
                  if (FAILED(hr))
                  {
                      deskFolder->Release();
                      appObject->Release();
                      return icon;
                  }
               
                  if (iconSize == 16)
                      hr = extractIcon->Extract(iconLocation, iconIndex, &tmpIcon, &icon, MAKELONG(32, 16));
                  else
                  hr = extractIcon->Extract(iconLocation, iconIndex, &icon, &tmpIcon, MAKELONG(iconSize, 16));
                  if (SUCCEEDED(hr))
                  {
                  DestroyIcon(tmpIcon);
                  }
                  extractIcon->Release();
                  appObject->Release();
                  deskFolder->Release();
               
                  return icon;
              }
            Сообщение отредактировано: shershen -
              ExpandedWrap disabled
                uses Windows,ShlObj;
                 
                function EGGetIcon(FileName:PChar; iconSize:Integer):HICON;
                var
                 tmpIcon:HICON;
                 deskFolder,appObject:IShellFolder;
                 pidlLocal, pidlRelative: PItemIDList;
                 extractIcon:IExtractIcon;
                 iconLocation:array[0..MAX_PATH-1] of Char;
                 iconIndex:integer;
                 pchEaten,dwAttrib,iconFlags:Cardinal;
                 hr:HRESULT;
                begin
                   Result:=0;
                 
                   if FAILED(SHGetDesktopFolder(deskFolder)) then exit;
                 
                   if FAILED(deskFolder.ParseDisplayName(0, nil, FileName, pchEaten, pidlLocal, dwAttrib)) then exit;
                 
                   pidlRelative := ILClone(ILFindLastID(pidlLocal));
                   ILRemoveLastID(pidlLocal);
                 
                   hr := deskFolder.BindToObject(pidlLocal, nil, IID_IShellFolder, appObject);
                   ILFree(pidlLocal);
                   if FAILED(hr) then exit;
                 
                   hr := appObject.GetUIObjectOf(0, 1, pidlRelative, IID_IExtractIconW, nil,extractIcon);
                   ILFree(pidlRelative);
                   if FAILED(hr) then exit;
                 
                   if FAILED(extractIcon.GetIconLocation(0, iconLocation, MAX_PATH, iconIndex, iconFlags)) then exit;
                 
                   if (iconSize = 16) then
                    hr := extractIcon.Extract(iconLocation, iconIndex, tmpIcon, Result, MAKELONG(32, 16))
                   else
                    hr := extractIcon.Extract(iconLocation, iconIndex, Result, tmpIcon, MAKELONG(iconSize, 16));
                   if SUCCEEDED(hr) then DestroyIcon(tmpIcon);
                end;
                 
                procedure TForm1.Button1Click(Sender: TObject);
                var
                 icon:HICON;
                begin
                 icon:=EGGetIcon('C:\WINDOWS\MEDIA\ding.wav',32);
                 Image1.Picture.Icon.Handle:=icon
                end;
                Krid, спасибо большое.

                Теперь другой вопрос, почему IExtractIcon::Extract на некоторые файлы возвращает S_FALSE?
                В Мсдн написано "The icon location and index are the same values returned by the IExtractIcon::GetIconLocation method. If IExtractIcon::Extract function returns S_FALSE, these values must specify an icon file name and index that form legal parameters for a call to ExtractIcon. " , но как-то это мне не сильно помогло...
                Сообщение отредактировано: shershen -
                  Если Extract возвращает S_FALSE, то это означает, что значения iconLocation и iconIndex (полученные в GetIconLocation) - валидны и определяют имя файла с иконкой и индекс (порядковый номер) этой иконки в файле. В этом случае проводник сам извлекает иконку либо по этим данным (передав их, например в ExtractIcon), либо из кэша (если иконка там есть).

                  Ну а если возвращается S_OK, то в принципе происходит тоже самое, но iconLocation и iconIndex могут быть не валидны и кэш иконок проводника может не использоваться (что несколько замедляет работу для большого кол-ва файлов). Иконки тут извлекает соотв. само приложение (т.е. метод Extract).

                  Вобщем-то всё зависит от флагов и от установленых расширений оболочки, реализующих интерфейс IExtractIcon для конкретных файлов.

                  Кстати, возвращаемое Extract'ом значение нужно (и важно) тому, кто пишет такие расширения.
                  А тебе в данном случае абсолютно без разницы, что возвращает Extract. Иконку ты всё равно получишь :) Результат вызова Extract'а по сути просто показывает, какие внутренние механизмы были использованы для получения иконки.
                    Цитата Krid @
                    Иконку ты всё равно получишь

                    Так я бы и не парился, если бы так и было, так ведь не получаю, пусто в иконках.
                      Так это не ошибка. Видимо для этого файла нет иконок там, где Extract их ищет - ни в самом файле, ни в кэше, ни в реестре, etc. Так что напрасно паришься. Это - by design :)

                      Ну а если тебе обязательно нужна иконка - бери дефолтную для этого типа файлов (через ExtractAssociatedIcon(EX)/SHGetFileInfo/etc.)
                        Теперь, пожалуй, все ясно :) Спасибо
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0325 ]   [ 16 queries used ]   [ Generated: 28.04.24, 13:37 GMT ]