From d9d99834f604402a2897037455261f9dd7d98c3f Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 7 Feb 2017 19:27:31 +0300 Subject: [PATCH] shell32: Implement IShellImageData::Decode() when created from file path. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/shell32/Makefile.in | 2 +- dlls/shell32/shellole.c | 45 ++++++++++++++++++++++++++++++++++++++-- include/shimgdata.idl | 9 +++++++- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in index 038db7fd204..970ecba4f65 100644 --- a/dlls/shell32/Makefile.in +++ b/dlls/shell32/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -D_SHELL32_ MODULE = shell32.dll IMPORTLIB = shell32 IMPORTS = uuid shlwapi user32 gdi32 advapi32 -DELAYIMPORTS = ole32 oleaut32 shdocvw version comctl32 +DELAYIMPORTS = ole32 oleaut32 shdocvw version comctl32 gdiplus EXTRALIBS = $(CORESERVICES_LIBS) # AUTHORS file is in the top-level directory EXTRAINCL = -I$(top_srcdir) diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c index deef21c6b8f..46a7b03105d 100644 --- a/dlls/shell32/shellole.c +++ b/dlls/shell32/shellole.c @@ -36,6 +36,7 @@ #include "shlobj.h" #include "shlguid.h" #include "shldisp.h" +#include "gdiplus.h" #include "shimgdata.h" #include "winreg.h" #include "winerror.h" @@ -811,6 +812,23 @@ HRESULT WINAPI SHCreateQueryCancelAutoPlayMoniker(IMoniker **moniker) return CreateClassMoniker(&CLSID_QueryCancelAutoPlay, moniker); } +static HRESULT gpstatus_to_hresult(GpStatus status) +{ + switch (status) + { + case Ok: + return S_OK; + case InvalidParameter: + return E_INVALIDARG; + case OutOfMemory: + return E_OUTOFMEMORY; + case NotImplemented: + return E_NOTIMPL; + default: + return E_FAIL; + } +} + /* IShellImageData */ typedef struct { @@ -818,6 +836,7 @@ typedef struct LONG ref; WCHAR *path; + GpImage *image; } ShellImageData; static inline ShellImageData *impl_from_IShellImageData(IShellImageData *iface) @@ -861,6 +880,7 @@ static ULONG WINAPI ShellImageData_Release(IShellImageData *iface) if (!ref) { + GdipDisposeImage(This->image); HeapFree(GetProcessHeap(), 0, This->path); SHFree(This); } @@ -871,10 +891,30 @@ static ULONG WINAPI ShellImageData_Release(IShellImageData *iface) static HRESULT WINAPI ShellImageData_Decode(IShellImageData *iface, DWORD flags, ULONG cx_desired, ULONG cy_desired) { ShellImageData *This = impl_from_IShellImageData(iface); + GpImage *image; + HRESULT hr; - FIXME("%p, %#x, %u, %u: stub\n", This, flags, cx_desired, cy_desired); + TRACE("%p, %#x, %u, %u\n", This, flags, cx_desired, cy_desired); - return E_NOTIMPL; + if (This->image) + return S_FALSE; + + if (flags & SHIMGDEC_LOADFULL) + FIXME("LOADFULL flag ignored\n"); + + hr = gpstatus_to_hresult(GdipLoadImageFromFile(This->path, &image)); + if (FAILED(hr)) + return hr; + + if (flags & SHIMGDEC_THUMBNAIL) + { + hr = gpstatus_to_hresult(GdipGetImageThumbnail(image, cx_desired, cy_desired, &This->image, NULL, NULL)); + GdipDisposeImage(image); + } + else + This->image = image; + + return hr; } static HRESULT WINAPI ShellImageData_Draw(IShellImageData *iface, HDC hdc, RECT *dest, RECT *src) @@ -1186,6 +1226,7 @@ static HRESULT create_shellimagedata_from_path(const WCHAR *path, IShellImageDat This->ref = 1; This->path = strdupW(path); + This->image = NULL; *data = &This->IShellImageData_iface; return S_OK; diff --git a/include/shimgdata.idl b/include/shimgdata.idl index 2e8429880a4..e913c576af4 100644 --- a/include/shimgdata.idl +++ b/include/shimgdata.idl @@ -27,11 +27,18 @@ cpp_quote("#ifndef _GDIPLUSENUMS_H") typedef DWORD InterpolationMode; cpp_quote("#endif") -cpp_quote("#ifndef _GDIPLUSHEADERS_H") +cpp_quote("#ifndef _GDIPLUSIMAGING_H") typedef BYTE EncoderParameters; +cpp_quote("#endif") + +cpp_quote("#ifndef _GDIPLUSHEADERS_H") typedef BYTE Image; cpp_quote("#endif") +cpp_quote("#define SHIMGDEC_DEFAULT 0x0") +cpp_quote("#define SHIMGDEC_THUMBNAIL 0x1") +cpp_quote("#define SHIMGDEC_LOADFULL 0x2") + [ object, uuid(53fb8e58-50c0-4003-b4aa-0c8df28e7f3a)