|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
[ Исходник ] - Получение эскиза файла/папки
Получение эскиза (миниатюры) файла/папки с использованием IExtractImage. Код:
unit ThumbnailImage; interface uses ActiveX, ShlObj, Windows, SysUtils; type IExtractImage = interface ['{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}'] function GetLocation(pszPathBuffer: LPWSTR; cchMax: DWORD; var pdwPriority: DWORD; var prgSize: TSize; dwRecClrDepth: DWORD; var pdwFlags: DWORD): HRESULT; stdcall; function Extract(var phBmpImage: HBITMAP): HRESULT; stdcall; end; const IEIFLAG_OFFLINE = $008; IEIFLAG_SCREEN = $020; IEIFLAG_QUALITY = $200; function GetThumbnailImage(const DisplayName: String; Width: Integer; Height: Integer): HBITMAP; implementation function GetThumbnailImage(const DisplayName: String; Width: Integer; Height: Integer): HBITMAP; var FilePath: String; FileName: String; DesktopFolder: IShellFolder; Eaten: ULONG; DirectoryItemIDList: PItemIDList; Attributes: ULONG; ShellFolder: IShellFolder; ExtractImage: IExtractImage; PathBuffer: array [0..MAX_PATH-1] of WideChar; Priority: DWORD; Size: TSize; Flags: DWORD; ColorDepth: DWORD; Res: HRESULT; begin Result:=0; FilePath:=ExcludeTrailingPathDelimiter(ExtractFilePath(DisplayName)); if FilePath[Length(FilePath)]=':' then FilePath:=IncludeTrailingPathDelimiter(FilePath); FileName:=ExtractFileName(DisplayName); SHGetDesktopFolder(DesktopFolder); DesktopFolder.ParseDisplayName(0, nil, StringToOleStr(FilePath), Eaten, DirectoryItemIDList, Attributes); DesktopFolder.BindToObject(DirectoryItemIDList, nil, IShellFolder, ShellFolder); CoTaskMemFree(DirectoryItemIDList); ShellFolder.ParseDisplayName(0, nil, StringToOleStr(ExtractFileName(FileName)), Eaten, DirectoryItemIDList, Attributes); ShellFolder.GetUIObjectOf(0, 1, DirectoryItemIDList, IExtractImage, nil, ExtractImage); CoTaskMemFree(DirectoryItemIDList); if Assigned(ExtractImage) then begin Priority:=0; Size.cx:=Width; Size.cy:=Height; Flags:=IEIFLAG_SCREEN or IEIFLAG_OFFLINE or IEIFLAG_QUALITY; ColorDepth:=32; Res:=ExtractImage.GetLocation(@PathBuffer[0], Length(PathBuffer), Priority, Size, ColorDepth, Flags); if (Res=NOERROR) or (Res=E_PENDING) then if not Succeeded(ExtractImage.Extract(Result)) then Result:=0; end; end; end. IExtractIcon в следующий раз. Пишу программы за еду. __________________ |
Эти 3 пользователя(ей) сказали Спасибо NumLock за это полезное сообщение: | ||
#2
|
||||
|
||||
У всех работает пример или нет? У меня при выборе папки вылетает с ошибкой "Invalid Image size", т.е. вроде как функция не возвращает картинки и далее получаем такое сообщение.
|
#3
|
||||
|
||||
запускай не из под Delphi, либо флажок "Stop..." убери.
Пишу программы за еду. __________________ |
#4
|
||||
|
||||
Зачот. Придётся логгером отдельно трассировать на ошибки-то? Надо бы потоки прикрутить или фильтрацию по типам, а то я с дуру на мусорную папку указал, так минуту ждал пока превьюшки появятся.
А можно по-подробнее о том, почему это не работает в самой среде? И что ещё за стоп-флажок? Что-то не помню такого. Вот так бы выглядело чуть по-лучше и тормозов бы поменьше ещё. Россия навсегда! Последний раз редактировалось uni, 30.11.2012 в 14:30. |
#5
|
||||
|
||||
зачем логгером? просто проверять результат функции GetThumbnailImage по-человечески, а не как я в примере набросал:
Код:
try ImageList1.Add(Bitmap, nil); except Bitmap.LoadFromResourceName(HInstance, 'FOLDER'); ImageList1.Add(Bitmap, nil); end; Пишу программы за еду. __________________ |
#6
|
||||
|
||||
Век живи, как говорится, никогда не обращал на эту штуку внимания. Попробовал тут в XE3 завести, думал, может заведётся, ан нет, пишет, что ресурса FOLDER не найдено.
Спасибо за исходник. Осталось только понять что там каждая из функций делает. Так вот прикольней смотрится, но не для всех дельфей, к сожалению: Россия навсегда! Последний раз редактировалось uni, 30.11.2012 в 14:38. |
#7
|
||||
|
||||
для Unicode версий нужно, как обычно, String смотреть и их приведения/не привидения к Wide. а так все в MSDN есть. проблем не должно быть.
Пишу программы за еду. __________________ |
#8
|
||||
|
||||
Не могу понять в чём отличие запуска функции в отдельном потоке (не работает). Картинки перестают доставаться. Вместо них показываются заглушки папочные. Begin и EndUpdate тоже можно было бы сразу добавить и мигания не будет, и быстрее загрузка будет.
Я ступил по поводу XE3, т.е. начал новый проект, а про ресурсы-то забыл. После копирования файла с описанием этого самого ресурса всё заработало. Осталось только понять как это делать в потоке, чтобы интерфейс не тупил. Россия навсегда! Последний раз редактировалось uni, 30.11.2012 в 17:24. |
#9
|
||||
|
||||
Я опять забыл, что в потоке-то своя локальная память потока, поэтому, когда мы работаем с COM, то нужно делать OleInitialize( nil ) и OleUninitialize прямо в функции потока. Вот в этом разница. Я, кстати, не заметил, в примере есть OleUninitialize? Вроде как его вызов обязателен.
А так всё работает. Россия навсегда! |
#10
|
|||
|
|||
Добрый день. Выложите пожалуйста ваш исходник на xe3
|
#11
|
||||
|
||||
Вот, кажется это он.
Россия навсегда! |
#12
|
|||
|
|||
Запустил все вложенные в этой теме примеры. На моих двух ПК - вместо превью картинок - изображения папок.
|
#13
|
|||
|
|||
Спасибо большое за пример!
Здравствуйте.
Спасибо большое за пример! 1) А как понять, что GetThumbnailImage не нашла изображение (например у *.pas файла)? У таких файлов HBITMAP был все равно ненулевой и по нему я не смог отличить. 2) Как сделать превью у txt или doc файлов? 3) Здесь можно выбирать размер картинки получаемой, напр. 64*64. А как остальные файлы (не картинки, напр. pas) - к ним получить иконку такого же размера? shGetFileInfo на сколько я понимаю, дает только 16*16 или 32*32 Последний раз редактировалось poiuyt555, 27.03.2013 в 13:49. |