const
SIIGBF_RESIZETOFIT = $00000000;
SIIGBF_BIGGERSIZEOK = $00000001;
SIIGBF_MEMORYONLY = $00000002;
SIIGBF_ICONONLY = $00000004;
SIIGBF_THUMBNAILONLY = $00000008;
SIIGBF_INCACHEONLY = $00000010;
type
SIIGBF = Integer;
IShellItemImageFactory = interface(IUnknown)
['{BCC18B79-BA16-442F-80C4-8A59C30C463B}']
function GetImage(size: TSize; flags: SIIGBF; out phbm: HBITMAP): HRESULT; stdcall;
end;
function GetThumbnailPtr(const aFileName: UTF8String; aSize: TSize; out Bitmap: HBITMAP): HRESULT;
var
ShellItemImage: IShellItemImageFactory;
begin
Result:= SHCreateItemFromParsingName(PWideChar(UTF8Decode(aFileName)), nil,
IShellItemImageFactory, ShellItemImage);
if Succeeded(Result) then
begin
Result:= ShellItemImage.GetImage(aSize, SIIGBF_THUMBNAILONLY, Bitmap);
end;
end;
function GetThumbnail(const aFileName: UTF8String; aSize: TSize): TBitmap;
var
hBmp: HBITMAP;
Status: HRESULT;
begin
Result:= nil;
Status := E_FAIL;
if (Win32MajorVersion > 5) then
begin
Status:= GetThumbnailPtr(aFileName, aSize, hBmp);
end;
if Succeeded(Status) then
begin
Result:= TBitmap.Create;
Result.Handle:= hBmp;
end;
end;
procedure TForm1.Button6Click(Sender: TObject);
var
sz: TSize;
begin
sz.cx := 100;
sz.cy := 100;
Image1.Picture.Assign(GetThumbnail(Edit1.Text, sz));
end;
...
Result := fileShellItemImage.GetImage(s, SIIGBF_THUMBNAILONLY, hBmp);
...
to:...
Result := fileShellItemImage.GetImage(s, SIIGBF_RESIZETOFIT, hBmp);
...
const
CLSID_LocalThumbnailCache: TGuid = '{50EF4544-AC9F-4A8E-B21B-8A26180DB13F}';
CLSID_SharedBitmap: TGuid = '{4db26476-6787-4046-b836-e8412a9e8a27}';
type
{$EXTERNALSYM WTS_FLAGS}
WTS_FLAGS = (
WTS_EXTRACT = 0,
WTS_INCACHEONLY = 1,
WTS_FASTEXTRACT = 2,
WTS_FORCEEXTRACTION = 4,
WTS_SLOWRECLAIM = 8,
WTS_EXTRACTDONOTCACHE = 32,
WTS_SCALETOREQUESTEDSIZE = 64,
WTS_SKIPFASTEXTRACT = 128,
WTS_EXTRACTINPROC = 256
);
{$EXTERNALSYM WTS_CACHEFLAGS}
WTS_CACHEFLAGS = (
WTS_DEFAULT = 0,
WTS_LOWQUALITY = 1,
WTS_CACHED = 2
);
PWTS_CACHEFLAGS = ^WTS_CACHEFLAGS;
{$EXTERNALSYM WTS_ALPHATYPE}
WTS_ALPHATYPE = (
WTSAT_UNKNOWN = 0,
WTSAT_RGB = 1,
WTSAT_ARGB = 2
);
{$EXTERNALSYM WTS_THUMBNAILID}
WTS_THUMBNAILID = record
rgbKey: array[0..15] of Byte;
end;
PWTS_THUMBNAILID = ^WTS_THUMBNAILID;
{$EXTERNALSYM ISharedBitmap}
ISharedBitmap = interface(IUnknown)
['{091162a4-bc96-411f-aae8-c5122cd03363}']
function GetSharedBitmap(out phbm: HBITMAP): HRESULT; stdcall;
function GetSize(out pSize: TSize): HRESULT; stdcall;
function GetFormat(out pat: WTS_ALPHATYPE): HRESULT; stdcall;
function InitializeBitmap(hbm: HBITMAP; wtsAT: WTS_ALPHATYPE): HRESULT; stdcall;
function Detach(out phbm: HBITMAP): HRESULT; stdcall;
end;
{$EXTERNALSYM IThumbnailCache}
IThumbnailCache = interface(IUnknown)
['{F676C15D-596A-4ce2-8234-33996F445DB1}']
function GetThumbnail(pShellItem: IShellItem; cxyRequestedThumbSize: UINT;
flags: WTS_FLAGS; out ppvThumb: ISharedBitmap; pOutFlags: PWTS_CACHEFLAGS;
pThumbnailID: PWTS_THUMBNAILID): HRESULT; stdcall;
function GetThumbnailByID(thumbnailID: WTS_THUMBNAILID; cxyRequestedThumbSize: UINT;
out ppvThumb: ISharedBitmap; pOutFlags: PWTS_CACHEFLAGS): HRESULT; stdcall;
end;
Procedure MirrorVertical(var Picture: TBitmap);
var BMP: TBitmap;
i,j: integer;
begin
BMP := TBitmap.Create;
BMP.Assign(Picture);
for i := 0 to BMP.Height-1 do
for j := 0 to BMP.Width-1 do
Picture.canvas.Pixels[j, BMP.Height-i-1] := BMP.canvas.Pixels[j, i];
BMP.free;
end;
procedure ResizeBitmap(Bitmap: TBitmap; const NewWidth, NewHeight: integer);
begin
Bitmap.Canvas.StretchDraw(
Rect(0, 0, NewWidth, NewHeight),
Bitmap);
Bitmap.SetSize(NewWidth, NewHeight);
end;
function GetThumbFromCache(AFileName: string; out Bmp: TBitmap; AMaxSize: Integer = 120): HRESULT;
var
thumbcache: IThumbnailCache;
sharedbmp: ISharedBitmap;
shellitem: IShellItem;
thumbflags: PWTS_CACHEFLAGS;
thumbid: PWTS_THUMBNAILID;
thumbsize: TSize;
hBmp: HBITMAP;
begin
if not Assigned(Bmp) then
Exit;
Result := CoInitialize(Nil);
Result := CoCreateInstance(
CLSID_LocalThumbnailCache,
nil,
CLSCTX_INPROC,
IThumbnailCache,
thumbcache
);
if Succeeded(Result) then
begin
Result := SHCreateItemFromParsingName(
PChar(AFileName),
nil,
IShellItem,
shellitem
);
if Succeeded(Result) then
begin
Result := thumbcache.GetThumbnail(
shellitem,
AMaxSize,
WTS_EXTRACT,
sharedbmp,
nil, //thumbflags,
nil //thumbid
);
if Succeeded(Result) then
begin
sharedbmp.GetSize(thumbsize);
Result := sharedbmp.GetSharedBitmap(hBmp);
if Succeeded(Result) then
begin
bmp.SetSize(thumbsize.cx, thumbsize.cy);
bmp.Handle := hBmp;
bmp.Dormant;
ResizeBitmap(bmp, AMaxSize, MulDiv(AMaxSize,thumbsize.cy, thumbsize.cx));
//FlipBmp(bmp);
MirrorVertical(Bmp);
end;
end;
CoUninitialize;
end;
end;
end;
(modified version of original...)
If this method succeeds, it returns S_OK (0x00000000), otherwise, it returns an HRESULT error code.
HRESULT error codes