Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получить значек desktop-а, SHGetFileInfo, SHGetDesktopFolder 
V
    Опции темы
~FoX~
  Дата 1.12.2009, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



Не могу получить иконку рабочего стола (синий прямоугольник с карандашом)...

Код

var
  desktop: IShellFolder;
  PIDL: PItemIDList;
  st: StrRet;
  ImageList1: TimageList;
  Flags: LongWord;
  SFI: TSHFileInfo;
  p: pchar;
begin
  SHGetDesktopFolder(desktop); //получаю интерфейс
  desktop.GetDisplayNameOf(PIDL, SHGDN_NORMAL, St);
  
  p := PChar(GetSpecialPath(CSIDL_DESKTOP)); //получаем полный путь к десктопу

  ImageList1 := TImageList.Create(ListView1); //создаем имиджлист для листа 
  ImageList1.Width := 32;
  ImageList1.Height := 32;
  ShareImages := True;

  ImageList1.Handle := SHGetFileInfo(p, 0, SFI, SizeOf(SFI), //подменяем системный имиджлист собственным
            SHGFI_SYSICONINDEX or SHGFI_SMALLICON); //собственно тут мне кажется и проблема...

  ListView1.LargeImages := ImageList1; //присовокупляем картинки к листу

  ListView1.Items.Add.Caption := GetDisplayName(PIDL, St); //получаем капшн дисктопа
  ListView1.Items.Add.ImageIndex := SFI.iIcon; //устанавливаем иконку
end;


function GetDisplayName(pidl: PItemIDList; const Value: STRRET): string; //получаем имя
begin
  with Value do
  case uType of
    STRRET_CSTR:   Result := PChar(@cStr[0]);
    STRRET_OFFSET: Result := PChar(LongWord(pidl) + uOffset);
    STRRET_WSTR:   Result := pOleStr;
  end;
end;

function GetSpecialPath(CSIDL: word): string; //получаем полный путь
var s:  string;
begin
  SetLength(s, MAX_PATH);
  if not SHGetSpecialFolderPath(0, PChar(s), CSIDL, true)
  then s := GetSpecialPath(CSIDL_APPDATA);
  result := PChar(s);
end;

Пробовал через SHGetSpecialFolderLocation и SHGetSpecialFolderPath ни чиего не меняется
Пробовал передавать в SHGetFileInfo атрибуты в место 0 с помощью  desktop.GetAttributesOf(0, PIDL, Flags); эффекта 0
Если в SHGetFileInfo указать конкретный SH объект, то вторая иконка будет ассоциативной с ним т.е. SHGetFileInfo(PChar('c:\1.txt')............ покажет ассоциативную иконку с *.тхт
Не понятно почему возникает артефакт в виде появления второго итема в ListBox-е с ассоциированной иконкой

Результат и желание в аттаче...

Это сообщение отредактировал(а) ~FoX~ - 1.12.2009, 18:20

Присоединённый файл ( Кол-во скачиваний: 33 )
Присоединённый файл  desktop.JPG 10,78 Kb


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
Snowy
Дата 1.12.2009, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Проблема в получении системного имаджлиста, а не иконки рабочего стола  smile
В листе всего 5 иконок...

Добавлено через 5 минут и 12 секунд
У меня ни один код из DRKB не заработал - все выдают лист из 5 элементов.
PM MAIL   Вверх
~FoX~
Дата 1.12.2009, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



Snowy, Да это понятное дело...

Цитата(~FoX~ @  1.12.2009,  19:16 Найти цитируемый пост)
 ImageList1.Handle := SHGetFileInfo(p, 0, SFI, SizeOf(SFI), //подменяем системный имиджлист собственным
            SHGFI_SYSICONINDEX or SHGFI_SMALLICON); //собственно тут мне кажется и проблема...



Не понятно по чему, описание десктопа в пространстве имен как и у любого объекта, только он является корнем, может у него где в реестре это хранится?


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
kami
Дата 1.12.2009, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



попробуй так:
Код

На форме:
  Image1: TImage;
  ilIcons: TImageList; // с флагом Shareimages:=True;

var
  FileInfo:TSHFileInfo;

  ZeroMemory(@FileInfo,SizeOf(TSHFileInfo));
  ilIcons.Handle := SHGetFileInfo(PChar(''),
     0,
     FileInfo,
     SizeOf(TSHFileInfo),
     SHGFI_USEFILEATTRIBUTES or
     SHGFI_ADDOVERLAYS or
     SHGFI_ICON or SHGFI_SMALLICON or
     SHGFI_SYSICONINDEX);
  // непосредственное получение иконки с добавлением ее в системный imageList
  ZeroMemory(@FileInfo,SizeOf(TSHFileInfo));
  SHGetFileInfo(PChar('1.desklink'), // в принципе, имя не главное - важно расширение .desklink
           FILE_ATTRIBUTE_NORMAL,
           FileInfo,
           SizeOf(TSHFileInfo),
           SHGFI_USEFILEATTRIBUTES or
           SHGFI_ICON or SHGFI_SMALLICON or
           //SHGFI_TYPENAME or
           SHGFI_SYSICONINDEX or SHGFI_ADDOVERLAYS);
  // и ее отрисовка
  ilIcons.Draw(Image1.Canvas,1,1,FileInfo.iIcon );
  Form1.Caption:=IntToStr(FileInfo.iIcon);
  Image1.Refresh;


Опробовано на XP SP2 и Vista Home Prem.

Это сообщение отредактировал(а) kami - 1.12.2009, 21:10
PM MAIL WWW   Вверх
kami
Дата 1.12.2009, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(Snowy @  1.12.2009,  19:39 Найти цитируемый пост)
У меня ни один код из DRKB не заработал - все выдают лист из 5 элементов.

А они и не выдадут больше, пока об этом не попросишь систему, указав нужное расширение и SHGFI_SYSICONINDEX

Упс... не посмотрел, что иконки нужны в ListView...
но в любом случае - после запроса иконки она появится в ImageList с индексом FileInfo.iIcon

Это сообщение отредактировал(а) kami - 1.12.2009, 21:30
PM MAIL WWW   Вверх
~FoX~
Дата 1.12.2009, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



kami, Дякую, но не наши методы... desklink - ассоциирован с десктопом, но это не решение... smile 


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
kami
Дата 1.12.2009, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(~FoX~ @  1.12.2009,  21:27 Найти цитируемый пост)
 desklink - ассоциирован с десктопом, но это не решение...

Да не вопрос - переделываем чуть-чуть код:

Код

На форме:
  Image1: TImage;
  ilIcons: TImageList; // с флагом Shareimages:=True;

var
  FileInfo:TSHFileInfo;

  desktop: IShellFolder;
  PIDL: PItemIDList;
  st: StrRet;
  Flags: LongWord;
  SFI: TSHFileInfo;
  p: pchar;
begin
  // получаем системный ImageList
  ZeroMemory(@FileInfo,SizeOf(TSHFileInfo));
  ilIcons.Handle := SHGetFileInfo(PChar(''),
     0,
     FileInfo,
     SizeOf(TSHFileInfo),
     SHGFI_USEFILEATTRIBUTES or
     SHGFI_ADDOVERLAYS or
     SHGFI_ICON or SHGFI_LARGEICON or
     SHGFI_SYSICONINDEX);
  
  SHGetDesktopFolder(desktop);
  desktop.GetDisplayNameOf(PIDL, SHGDN_NORMAL, St);

  p := PChar(GetSpecialPath(CSIDL_DESKTOP)); 

  // добавляем в системный ImageList иконку десктопа.
  SHGetFileInfo(p, 0, FileInfo, SizeOf(FileInfo), 
            SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
  // отрисовываем ее.
  ilIcons.Draw(Image1.Canvas,1,1,FileInfo.iIcon);
  Form1.Caption:=IntToStr(FileInfo.iIcon);
  Image1.Refresh;
end;

PM MAIL WWW   Вверх
~FoX~
Дата 1.12.2009, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



Получаю иконку папки  smile 
И кстати что такое SHGFI_ADDOVERLAYS ?

Это сообщение отредактировал(а) ~FoX~ - 1.12.2009, 22:02


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
kami
Дата 1.12.2009, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Код

const
  SHGFI_ADDOVERLAYS=$20;

Не определена в VCL.

Цитата(~FoX~ @  1.12.2009,  22:00 Найти цитируемый пост)
Получаю иконку папки  

Иконка папки под индексом 1.
А иконка десктопа получается под индексом 5 после выполнения кода.
Сейчас попробую на виртуалке на XP
PM MAIL WWW   Вверх
kami
Дата 1.12.2009, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Мда...
тот вариант не прокатил - на Висте нормально, в XP не то...
Зато вот так работает и там и там, и заморочек гораздо меньше:

Код

procedure TForm1.FormCreate(Sender: TObject);
var
  PIDL: PItemIDList;
  FileInfo:TSHFileInfo;
begin
  // получаем системный ImageList
  ZeroMemory(@FileInfo,SizeOf(TSHFileInfo));
  ilIcons.Handle := SHGetFileInfo(PChar(''),
     0,
     FileInfo,
     SizeOf(TSHFileInfo),
     SHGFI_USEFILEATTRIBUTES or
     SHGFI_ADDOVERLAYS or
     SHGFI_ICON or SHGFI_LARGEICON or
     SHGFI_SYSICONINDEX);
  // Получили. Воспользуемся теперь тем, что в SHGetFileInfo можно указывать не только
  // пути к папке/файлу, но и PIDL-ы
  if SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, PIDL)<>S_OK then
    exit;
  // узнали PIDL десктопа
  SHGetFileInfo(pointer(PIDL), 0, FileInfo, SizeOf(FileInfo), //добавили его иконку в системный ImageList, узнав ее индекс
            SHGFI_SYSICONINDEX or SHGFI_LARGEICON or SHGFI_PIDL);

  // и отрисовали иконку SysImageList с полученным индексом.
  ilIcons.Draw(Image1.Canvas,1,1,FileInfo.iIcon );
  Caption:=IntToStr(FileInfo.iIcon);
  Image1.Refresh;

  CoTaskMemFree(PIDL);
end;


Это сообщение отредактировал(а) kami - 1.12.2009, 22:38
PM MAIL WWW   Вверх
~FoX~
Дата 1.12.2009, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



kami, Понял в чем я накололся....

отвлечение от темы:  CoTaskMemFree(PIDL); Это что?
Это освобождение Memloc?

Это сообщение отредактировал(а) ~FoX~ - 1.12.2009, 23:11


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
kami
Дата 1.12.2009, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



MSDN
Читать про параметр ppidl
Объявлена в ActiveX.pas

Добавлено через 3 минуты и 17 секунд
Все же MSDN говорит, что лучше воспользоваться SHGetFolderLocation, но там для освобождения PIDL требуется вызов ILFree, а она в D7 не объявлена, самому объявлять чуть-чуть лень smile

Добавлено через 5 минут и 40 секунд
procedure ILFree(pidl:PItemIDList); stdcall; external 'shell32.dll'
вроде так...
PM MAIL WWW   Вверх
~FoX~
Дата 2.12.2009, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



Цитата(kami @  2.12.2009,  00:18 Найти цитируемый пост)
Все же MSDN говорит, что лучше воспользоваться SHGetFolderLocation, но там для освобождения PIDL требуется вызов ILFree, а она в D7 не объявлена, самому объявлять чуть-чуть лень smile

ILFree   - кусок malloc-а.....
Код

IMalloc := nil; 
Я же всю структуру освобождаю...


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
kami
Дата 2.12.2009, 00:37 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(~FoX~ @  2.12.2009,  00:01 Найти цитируемый пост)
Я же всю структуру освобождаю...

Честно - не копенгаген в этих вопросах, да и Delphi хорошо следит за интерфейсами. Но PIDL - это же не интерфейс... В общем, написано в MSDN люминий, значит люминий. smile
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0575 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.