[PATCH 2/4] shell32: Implement IShellImageData::Decode() when created from file path

Nikolay Sivov nsivov at codeweavers.com
Mon Feb 6 17:12:52 CST 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/shell32/Makefile.in |  2 +-
 dlls/shell32/shellole.c  | 45 +++++++++++++++++++++++++++++++++++++++++++--
 include/Makefile.in      |  1 +
 include/gdiplus.h        |  2 ++
 include/gdiplusheaders.h | 24 ++++++++++++++++++++++++
 include/shimgdata.idl    |  8 ++++++++
 6 files changed, 79 insertions(+), 3 deletions(-)
 create mode 100644 include/gdiplusheaders.h

diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index 038db7fd20..970ecba4f6 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 deef21c6b8..46a7b03105 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/Makefile.in b/include/Makefile.in
index 9f615cd783..124bfd76aa 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -373,6 +373,7 @@ HEADER_SRCS = \
 	gdiplusenums.h \
 	gdiplusflat.h \
 	gdiplusgpstubs.h \
+	gdiplusheaders.h \
 	gdiplusimaging.h \
 	gdiplusinit.h \
 	gdiplusmem.h \
diff --git a/include/gdiplus.h b/include/gdiplus.h
index e85343b7c1..8d08628121 100644
--- a/include/gdiplus.h
+++ b/include/gdiplus.h
@@ -38,6 +38,7 @@ namespace Gdiplus
 #include "gdipluscolormatrix.h"
 #include "gdiplusgpstubs.h"
 #include "gdipluseffects.h"
+#include "gdiplusheaders.h"
 
     namespace DllExports
     {
@@ -59,6 +60,7 @@ namespace Gdiplus
 #include "gdipluscolormatrix.h"
 #include "gdiplusgpstubs.h"
 #include "gdipluseffects.h"
+#include "gdiplusheaders.h"
 
 #include "gdiplusflat.h"
 
diff --git a/include/gdiplusheaders.h b/include/gdiplusheaders.h
new file mode 100644
index 0000000000..f28aed9228
--- /dev/null
+++ b/include/gdiplusheaders.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017 Nikolay Sivov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _GDIPLUSHEADERS_H
+#define _GDIPLUSHEADERS_H
+
+/* FIXME: C++ wrappers go here */
+
+#endif /* _GDIPLUSHEADERS_H */
diff --git a/include/shimgdata.idl b/include/shimgdata.idl
index 2e8429880a..e0a63255a6 100644
--- a/include/shimgdata.idl
+++ b/include/shimgdata.idl
@@ -29,9 +29,17 @@ cpp_quote("#endif")
 
 cpp_quote("#ifndef _GDIPLUSHEADERS_H")
 typedef BYTE EncoderParameters;
+cpp_quote("#endif")
+
+/* Wine does not define GDI+ class wrappers */
+cpp_quote("#if defined(__WINESRC__) || !defined(_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)
-- 
2.11.0




More information about the wine-patches mailing list