-
К вопросу о вытаскивании иконок размером 48х48 и более. Есть чудесный код, многим понравится, он отлично вытаскивает иконки указаного размера у файлов и папок. Вопрос в следующем: когда в проводнике (виста или вин7) в опциях папки отключено "всегда показывать значки а не искизы", то папки, в которых есть рисунки (а также графические файлы) отображаются с рисунками - выглядит так, все видели: http://i041.radikal.ru/1012/3b/2925a25653d6.pngВопрос: что нужно добавить в коде, чтобы было как на скрине выше (рисунки в виде эскизов, а папки с рисунками с вложеными миниатюрами). Понимаю, что можно отдельно все вытаскивать, но как быть с отображением папок? Может еще есть какойто ключик (больше чем уверен), который будет иконки в виде эскизов возвращать? Подскажите, пожалуйста.вот код модуля ----------------------
unit GetBigIcon;
interface
uses ShellApi, Commctrl, ShlObj, Windows, Sysutils, Graphics;
const
SHIL_LARGE = $00; SHIL_SMALL = $01; SHIL_EXTRALARGE= $02; SHIL_SYSSMALL = $03; SHIL_JUMBO = $04; IID_IImageList: TGUID= '';
Procedure GetIconFromFile(aFile:String; var aIcon : TIcon; SHIL_FLAG: Cardinal);
implementation
function GetImageListSH(SHIL_FLAG:Cardinal): HIMAGELIST;
type _SHGetImageList = function (iImageList: integer; const riid: TGUID; var ppv: Pointer): hResult; stdcall;
var Handle: THandle; SHGetImageList: _SHGetImageList;
begin Result:= 0;
Handle:= LoadLibrary('Shell32.dll');
if Handle<>S_OK then
try
SHGetImageList:=GetProcAddress(Handle, PChar(727));
if Assigned(SHGetImageList) and (Win32Platform=VER_PLATFORM_WIN32_NT) then SHGetImageList(SHIL_FLAG, IID_IImageList, Pointer(Result));
finally
FreeLibrary(Handle);
end;
end;
Procedure GetIconFromFile(aFile:String; var aIcon : TIcon; SHIL_FLAG: Cardinal);
var aImgList: HIMAGELIST; SFI: TSHFileInfo;aIndex: integer;
Begin
FillChar(SFI,Sizeof(SFI),#0);
SHGetFileInfo(PChar(aFile),0, SFI,SizeOf(TSHFileInfo),
SHGFI_ICON or SHGFI_LARGEICON or SHGFI_SHELLICONSIZE or SHGFI_SYSICONINDEX or SHGFI_TYPENAME or SHGFI_DISPLAYNAME);
if not Assigned(aIcon) then aIcon:= TIcon.Create;
aImgList:= GetImageListSH(SHIL_FLAG);
aIndex := SFI.iIcon;
aIcon.Handle := ImageList_GetIcon( aImgList, aIndex, ILD_NORMAL );
End;
end.
---------------------- Использование (на форме кнопка и image):
uses getbigicon;
...
procedure TForm1.Button1Click(Sender: TObject);
var ic:ticon;
begin
ic:=ticon.Create;
GetIconFromFile('c:\windows' , ic, SHIL_JUMBO); image1.Picture.Icon:=ic;
ic.Free;
P.S. Нашел тут похожий вопрос http://pda.delphimaster.net/?id=1256910300&n=0 , вот, как решение
-
-
Блин, ну хоть кто-нить отпишите, плз, с вистой\7 и с rad 2010 - никак обгрызеные папки не могу победить. Значки у файлов (если есть) при помощи юнита выше - отображаются на ура (думал, что чтото с разрешением ико не так - но значки файлов больше по размеру значка папки выводятся норм), а вот с папками беда. Именно при aIndex=1 (иконка с папкой) выводит обкусаный вариант при SHIL_FLAG=SHIL_JUMBO. Попробовал на 2х разных пк - с 7 и 2008 - тоже самое. На буржуйских форумах что-то писали про PNG формат, который может вступать в силу в этот момент при запросе джумбо, но тогда почему только у папковой икошки? P.S. пока ковырялся нашел еще одну фичу - при aIcon.Handle := ImageList_GetIcon( aImgList, aIndex, ILD_NORMAL); это значение может принимать такие (можно затемненные икошки выводить и др, как в проводнике, когда просмотр скрытых файлов включен - они такие..ммм.. полупрозрачненькие)
Может кто-то уже себе версию Codegear XE поставил, попробуйте код, плз, может какието несоответствия rad-vista/7 ?
-
..Да, забыл, один товарищь написал на почту - (при использовании) в image1.Picture.Icon:=ic; посоветовал image1.Picture.Icon.assign(ic); - не помогло.
-
попробывал на Xe - тоже самое. вообщем вопрос открыт: как из системы выдрать иконки папок с превьюшками: http://i041.radikal.ru/1012/3b/2925a25653d6.pngв опциях тотал (там где эскизы) есть пометка, что их выдирает плагин на базе Ole2. Как не искал, ничего не нашел на эту тему. Пробовал через AxtiveX импортнуть ShellFolder (там в конце списка есть Shell..) тоже не получилось с этим. Пробовал при помощи thumbnail, но там только превьюшки файлов, а попытка передать IExtractImage папку в качестве параметра вызывает ошибку выполнения. Скажите хотябы в какую сторону копать..
-
иконки с первьюшками скорее всего рисуте какое-то расширение проводника, думаю вряд ли доберешься, проще самому сделать.
-
2 Eraser .."какое-то расширение проводника" :) так если эта библиотека, то проще подключить и функцию юзать, чем заниматься отрисовкой под углом вида вложеных рисунков и вида папки с тенями.. и патом тотал командер это же делает както..
-
> и патом
<offtop> Не надо "коверкать" русский язык </offtop>
-
> [6] Gu (22.12.10 03:26)
эта библиотека наверняка без документации и может менятся в зависисмости даже от билдов системы. задача то какая?
-
Задача: на винде начиная с виста (vista, win7, win 2008) вытащить иконку (или битмап) указаной папки. Но не простую иконку, а такую как на скрине http://i041.radikal.ru/1012/3b/2925a25653d6.png т.е. если в папке есть рисунки или другие документы, которые при включенных эскизах и больших значках в проводнике отображают папку как превью с вложеными миниатюрами.
-
Если через SHGetFileInfo не получается - то не получится.
-
тотал вытаскивает через ole2, писал выше, значит както можно, он же сторонний продукт, в винду не входит, но может. а SHGetFileInfo может какие новые ключики появились начиная с виста, скока не лазил ничего не нахожу, на буржуйских форумах тоже все молчат.
-
на одном форуме дале такой совет: >> думаю, тут работает несколько ShellExtension-библиотек, и тебе придется использовать их интерфейсы
никто не имел с этим дело под дельфями?
-
1. пример есть в "Руководстве разработчика" Тейксейра, Пачеко. 2. глянь у Rouse'а http://rouse.drkb.ru/ по-моему там что-то было по расширениям проводника.
-
Я нашёл ответ на ваш вопрос! С ума сойти. Прямое решение искалось 3 года Превьюшки можно получать через IShell Вот сорс модуля. Надеюсь, он влезет целиком Правда навскидку в этом модуле у папок проблемы с полупрозрачностью, выглядят они не очень, но это уже технические мелочи. PDF, всякие JPEG и пр. файлы, которые отображает проводник в режиме thumbnail, получаются на ура. unit ShellObjHelper;
interface
uses
Windows, ShlObj, ActiveX, ShellAPI, Graphics, StrUtils;
type
IExtractImage = interface
['']
function GetLocation(Buffer: PWideChar;
BufferSize: DWORD;
var Priority: DWORD;
var Size: TSize;
ColorDepth: DWORD;
var Flags: DWORD): HResult; stdcall;
function Extract(var BitmapHandle: HBITMAP): HResult; stdcall;
end;
IRunnableTask = interface
['']
function Run: HResult; stdcall;
function Kill(fWait: BOOL): HResult; stdcall;
function Suspend: HResult; stdcall;
function Resume: HResult; stdcall;
function IsRunning: Longint; stdcall;
end;
const
ITSAT_MAX_PRIORITY = 2;
ITSAT_MIN_PRIORITY = 1;
ITSAT_DEFAULT_PRIORITY = 0;
IEI_PRIORITY_MAX = ITSAT_MAX_PRIORITY;
IEI_PRIORITY_MIN = ITSAT_MIN_PRIORITY;
IEIT_PRIORITY_NORMAL = ITSAT_DEFAULT_PRIORITY;
IEIFLAG_ASYNC = $001; extract
IEIFLAG_CACHE = $002; cache
IEIFLAG_ASPECT = $004; to
IEIFLAG_OFFLINE = $008; // any content needs for the rendering
IEIFLAG_GLEAM = $010; // does the image have a gleam? this will be
// returned if it does
IEIFLAG_SCREEN = $020; // render as if for the screen (this is
exlusive
// with IEIFLAG_ASPECT )
IEIFLAG_ORIGSIZE = $040; // render to the approx size passed, but crop if
// neccessary
IEIFLAG_NOSTAMP = $080; // returned from the extractor if it does NOT
want
// an icon stamp on the thumbnail
IEIFLAG_NOBORDER = $100; // returned from the extractor if it does NOT
want
// an a border around the thumbnail
IEIFLAG_QUALITY = $200; // passed to the Extract method to indicate that
// a slower, higher quality image is desired,
// re-compute the thumbnail
// Delphi 3 SysUtils does not have this function
function ExcludeTrailingBackslash(const Src: string): string;
// IShellFolder methods helper
procedure ShellFolderBindToObject(const ShellFolder: IShellFolder;
PIDL: PItemIDList; const riid: TGUID; out pv);
function ShellFolderGetUIObjectOf(const ShellFolder: IShellFolder;
cidl: DWORD; var PIDL: PItemIDList; riid: TGUID; out pv): Boolean;
procedure ShellFolderParseDisplayName(const ShellFolder: IShellFolder;
const DisplayName: string; out PIDL: PItemIDList);
function ShellFolderGetExtractImage(const ShellFolder: IShellFolder;
const RelativeFileName: string; Malloc: IMalloc;
out XtractImage: IExtractImage): Boolean;
function GetExtractImageItfPtr(const FileName: string;
out XtractImage: IExtractImage): Boolean;
function GetFileLargeIcon(const FileName: string;
out LargeIcon: TIcon): Boolean;
function ExtractImageGetFileThumbnail(const XtractImage: IExtractImage;
ImgWidth, ImgHeight, ImgColorDepth: Integer; var Flags: DWORD; Bmp:
TBitmap;
out RunnableTask: IRunnableTask): Boolean;
function GetSysImgListIndex(const FileName: string): Integer;
procedure GetShellFolderItfPtr(const FolderName: string; Malloc: IMalloc;
out TargetFolder: IShellFolder);
function GetBitmapFromFile(const FileName: String): TGraphic;
implementation
uses SysUtils, ComObj;
function ExcludeTrailingBackslash(const Src: string): string;
begin
Result := Src;
if AnsiLastChar(Result) = '\' then
SetLength(Result, Pred(Length(Result)));
end;
procedure ShellFolderBindToObject(const ShellFolder: IShellFolder;
PIDL: PItemIDList; const riid: TGUID; out pv);
begin
OleCheck(ShellFolder.BindToObject(PIDL, nil, riid,
Pointer(pv)pv));
end;
function ShellFolderGetUIObjectOf(const ShellFolder: IShellFolder;
cidl: DWORD; var PIDL: PItemIDList; riid: TGUID; out pv): Boolean;
begin
Result := NOERROR = ShellFolder.GetUIObjectOf(0, cidl, PIDL,
riid, nil, Pointer(pv)pv);
end;
procedure ShellFolderParseDisplayName(const ShellFolder: IShellFolder;
const DisplayName: string; out PIDL: PItemIDList);
var
Attributes, Eaten: DWORD;
begin
OleCheck(ShellFolder.ParseDisplayName(0, nil,
PWideChar(WideString(DisplayName)), Eaten, PIDL, Attributes));
end;
function ShellFolderGetExtractImage(const ShellFolder: IShellFolder;
const RelativeFileName: string; Malloc: IMalloc;
out XtractImage: IExtractImage): Boolean;
var
PIDL: PItemIDList;
begin
ShellFolderParseDisplayName(ShellFolder, RelativeFileName, PIDL);
Result := ShellFolderGetUIObjectOf(ShellFolder, 1, PIDL,
IExtractImage, XtractImage);
Malloc.Free(PIDL);
end;
function GetExtractImageItfPtr(const FileName: string;
out XtractImage: IExtractImage): Boolean;
var
TargetFolder: IShellFolder;
FilePath: string;
ItemIDList: PItemIDList;
Malloc: IMalloc;
begin
FilePath := ExcludeTrailingBackslash(ExtractFilePath(FileName));
OleCheck(SHGetMalloc(Malloc));
GetShellFolderItfPtr(FilePath, Malloc, TargetFolder);
ShellFolderParseDisplayName(TargetFolder, ExtractFileName(FileName),
ItemIDList);
try
Result := ShellFolderGetUIObjectOf(TargetFolder, 1, ItemIDList,
IExtractImage, XtractImage);
finally
Malloc.Free(ItemIDList);
end;
end;
-
Вторая часть (не влезла просто):
function GetFileLargeIcon(const FileName: string; out LargeIcon: TIcon):
Boolean;
var
SFI: TSHFileInfo;
begin
if 0 <> SHGetFileInfo(PChar(FileName), FILE_ATTRIBUTE_ARCHIVE, SFI,
sizeof(SFI), SHGFI_ICON or SHGFI_LARGEICON) then
begin
LargeIcon := TIcon.Create;
LargeIcon.Handle := SFI.hIcon;
Result := True;
end else
Result := False;
end;
function ExtractImageGetFileThumbnail(const XtractImage: IExtractImage;
ImgWidth, ImgHeight, ImgColorDepth: Integer; var Flags: DWORD; Bmp:
TBitmap;
out RunnableTask: IRunnableTask): Boolean;
var
Size: TSize;
Buf: array[0..MAX_PATH] of WideChar;
BmpHandle: HBITMAP;
Priority: DWORD;
GetLocationRes: HRESULT;
procedure FreeAndNilBitmap;
begin
FreeAndNil(Bmp);
Bmp.Free;
Bmp := nil;
end;
begin
Result := False;
RunnableTask := nil;
Size.cx := ImgWidth;
Size.cy := ImgHeight;
Priority := IEIT_PRIORITY_NORMAL;
Flags := Flags or IEIFLAG_ASYNC;
GetLocationRes := XtractImage.GetLocation(Buf, sizeof(Buf), Priority,
Size,
ImgColorDepth, Flags);
if (GetLocationRes = NOERROR) or (GetLocationRes = E_PENDING) then
begin
if GetLocationRes = E_PENDING then
begin
if S_OK <> XtractImage.QueryInterface(IRunnableTask, RunnableTask)
then
RunnableTask := nil;
end;
try
OleCheck(XtractImage.Extract(BmpHandle)); time.
available
method
the process.
Bmp.Handle := BmpHandle;
Result := True;
except
on E: EOleSysError do
begin
OutputDebugString(PChar(string(E.ClassName) + ': ' + E.Message));
FreeAndNilBitmap;
Result := False;
end
else
begin
FreeAndNilBitmap;
raise;
end;
end;
end;
end;
function GetSysImgListIndex(const FileName: string): Integer;
var
SFI: TSHFileInfo;
begin
SHGetFileInfo(PChar(FileName), 0, SFI, sizeof(TSHFileInfo),
SHGFI_SYSICONINDEX);
Result := SFI.iIcon;
end;
procedure GetShellFolderItfPtr(const FolderName: string; Malloc: IMalloc;
out TargetFolder: IShellFolder);
var
DesktopFolder: IShellFolder;
ItemIDList: PItemIDList;
begin
OleCheck(SHGetDesktopFolder(DesktopFolder));
ShellFolderParseDisplayName(DesktopFolder, FolderName, ItemIDList);
try
ShellFolderBindToObject(DesktopFolder, ItemIDList, IShellFolder,
TargetFolder);
finally
Malloc.Free(ItemIDList);
end;
end;
function GetBitmapFromFile(const FileName: String): TGraphic;
var
XtractImage: IExtractImage;
Bmp: TBitmap;
Icon: TIcon;
ColorDepth: Integer;
Flags: DWORD;
RT: IRunnableTask;
begin
Flags := DWORD(IEIFLAG_OFFLINE) or DWORD(IEIFLAG_SCREEN);
ColorDepth := 32;
Result := nil;
Icon := nil;
Bmp := TBitmap.Create;
try
if GetFileLargeIcon(FileName, Icon) then
Result := Icon;
if GetExtractImageItfPtr(FileName, XTractImage) and
ExtractImageGetFileThumbnail(XtractImage, 256, 256, ColorDepth,
Flags, Bmp, RT) then
begin
Result := Bmp;
Icon.Free;
end
else
Bmp.Free;
except
end;
end;
end.
-
Комментарии в начале кода съехали. Там где объявление констант.
-
-
-
> Eraser © (12.10.11 04:15) [18]
Во! То, что надо, большое спасибо, буду разбираться
-
Удалено модератором
-
Удалено модератором
|