Hola gente del Foro!
Hace un tiempo buscando por la red encontré un código que me devuelve una miniatura de un archivo o su ícono.
Utiliza IExtract para hacer esto.
Funciona correctamente con imágenes, archivos Word, Excel, PDF, etc.
Cuando quiero obtener la miniatura de un archivo .odt (Open/LibreOffice) se cuelga el programa.
Os dejo a continuación adjunto los fuentes de un pequeño programa ejemplo.
ShObjIdlQuot.pas es una unidad con la definición de cosas auxiliares.
ShellObjHelper.pas es la unidad que hace el trabajo.
UFMMain.pas/dfm es el programa ejemplo que utiliza estas unidades.
Por lo que vi y hasta donde puedo llegar con mis conocimientos:
Se llama a GetExtractImageItfPtr (Archivo, XtractImage)
XtractImage es diferente de nil.
Se llama a ExtractImageGetFileThumbnail(XtractImage, MINIATURA_WIDTH, MINIATURA_HEIGHT, ColorDepth, Flags, RT, Bmp)
Dentro de este procedimiento se llama a XtractImage.GetLocation(...)
Con varios archivos devuelve NOERROR (0) o E_PENDING (-24...)
Si lo llamo con un archivo que no sea .odt XtractImage sigue siendo diferente de nil.
Si es .odt XtractImage se vuelve nil y todo empieza a fallar.
Espero que alguien con conocimientos de la API o de estas interfaces me pueda dar una solución
Gracias!
Código Delphi
[-]
function ExtractImageGetFileThumbnail(const XtractImage: IExtractImage; ImgWidth, ImgHeight, ImgColorDepth: Integer;
var Flags: DWORD; out RunnableTask: IRunnableTask; out Bmp: TBitmap): Boolean;
var
Size: TSize;
Buf: array [0 .. MAX_PATH] of WideChar;
BmpHandle: HBITMAP;
Priority: DWORD;
GetLocationRes: HRESULT;
procedure FreeAndNilBitmap;
begin
{$IFNDEF DELPHI3}
FreeAndNil(Bmp);
{$ELSE}
Bmp.Free;
Bmp := nil;
{$ENDIF}
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;
Bmp := TBitmap.Create;
try
OleCheck(XtractImage.Extract(BmpHandle)); Bmp.PixelFormat := pf32Bit;
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;