Alexander Scott-Johns : ole32: Add support for rendering METAFILEPICT clipboard objects.

Alexandre Julliard julliard at winehq.org
Fri Jan 28 12:30:15 CST 2011


Module: wine
Branch: master
Commit: 0f4fbd30f6bf3d2ef471d3d75307c7fa8a7df137
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0f4fbd30f6bf3d2ef471d3d75307c7fa8a7df137

Author: Alexander Scott-Johns <alexander.scott.johns at googlemail.com>
Date:   Tue Jan 25 15:09:21 2011 +0000

ole32: Add support for rendering METAFILEPICT clipboard objects.

---

 dlls/ole32/clipboard.c |   97 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 96 insertions(+), 1 deletions(-)

diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c
index 67b4350..9110f27 100644
--- a/dlls/ole32/clipboard.c
+++ b/dlls/ole32/clipboard.c
@@ -478,6 +478,62 @@ static HRESULT dup_global_mem( HGLOBAL src, DWORD flags, HGLOBAL *dst )
     return S_OK;
 }
 
+/***********************************************************************
+ *                    dup_metafilepict
+ *
+ * Helper function to duplicate a handle to a METAFILEPICT, and the
+ * contained HMETAFILE.
+ */
+static HRESULT dup_metafilepict(HGLOBAL src, HGLOBAL *pdest)
+{
+    HRESULT hr;
+    HGLOBAL dest;
+    METAFILEPICT *dest_ptr;
+
+    *pdest = NULL;
+
+    /* Copy the METAFILEPICT structure. */
+    hr = dup_global_mem(src, GMEM_DDESHARE|GMEM_MOVEABLE, &dest);
+    if (FAILED(hr)) return hr;
+
+    dest_ptr = GlobalLock(dest);
+    if (!dest_ptr) return E_FAIL;
+
+    /* Give the new METAFILEPICT a separate HMETAFILE. */
+    dest_ptr->hMF = CopyMetaFileW(dest_ptr->hMF, NULL);
+    if (dest_ptr->hMF)
+    {
+       GlobalUnlock(dest);
+       *pdest = dest;
+       return S_OK;
+    }
+    else
+    {
+       GlobalUnlock(dest);
+       GlobalFree(dest);
+       return E_FAIL;
+    }
+}
+
+/***********************************************************************
+ *                    free_metafilepict
+ *
+ * Helper function to GlobalFree a handle to a METAFILEPICT, and also
+ * free the contained HMETAFILE.
+ */
+static void free_metafilepict(HGLOBAL src)
+{
+    METAFILEPICT *src_ptr;
+
+    src_ptr = GlobalLock(src);
+    if (src_ptr)
+    {
+        DeleteMetaFile(src_ptr->hMF);
+        GlobalUnlock(src);
+    }
+    GlobalFree(src);
+}
+
 /************************************************************
  *              render_embed_source_hack
  *
@@ -744,6 +800,9 @@ static HRESULT get_data_from_global(IDataObject *data, FORMATETC *fmt, HGLOBAL *
     return hr;
 }
 
+/***************************************************************************
+ *         get_data_from_enhmetafile
+ */
 static HRESULT get_data_from_enhmetafile(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
 {
     HENHMETAFILE copy;
@@ -768,6 +827,34 @@ static HRESULT get_data_from_enhmetafile(IDataObject *data, FORMATETC *fmt, HGLO
     return hr;
 }
 
+/***************************************************************************
+ *         get_data_from_metafilepict
+ */
+static HRESULT get_data_from_metafilepict(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
+{
+    HGLOBAL copy;
+    HRESULT hr;
+    FORMATETC mem_fmt;
+    STGMEDIUM med;
+
+    *mem = NULL;
+
+    mem_fmt = *fmt;
+    mem_fmt.tymed = TYMED_MFPICT;
+
+    hr = IDataObject_GetData(data, &mem_fmt, &med);
+    if(FAILED(hr)) return hr;
+
+    hr = dup_metafilepict(med.u.hMetaFilePict, &copy);
+    if(FAILED(hr)) return hr;
+
+    *mem = copy;
+
+    ReleaseStgMedium(&med);
+
+    return hr;
+}
+
 /***********************************************************************
  *                render_format
  *
@@ -801,6 +888,11 @@ static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
     {
         hr = get_data_from_enhmetafile(data, fmt, &clip_data);
     }
+    else if(fmt->tymed & TYMED_MFPICT)
+    {
+        /* Returns global handle to METAFILEPICT, containing a copied HMETAFILE */
+        hr = get_data_from_metafilepict(data, fmt, &clip_data);
+    }
     else
     {
         FIXME("Unhandled tymed %x\n", fmt->tymed);
@@ -812,7 +904,10 @@ static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
         if ( !SetClipboardData(fmt->cfFormat, clip_data) )
         {
             WARN("() : Failed to set rendered clipboard data into clipboard!\n");
-            GlobalFree(clip_data);
+            if(fmt->tymed & TYMED_MFPICT)
+                free_metafilepict(clip_data);
+            else
+                GlobalFree(clip_data);
             hr = CLIPBRD_E_CANT_SET;
         }
     }




More information about the wine-cvs mailing list