Alexandre Julliard : user32: Synthesize metafile clipboard formats on the user32 side.

Alexandre Julliard julliard at winehq.org
Wed Sep 7 10:48:41 CDT 2016


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Sep  7 10:51:21 2016 +0900

user32: Synthesize metafile clipboard formats on the user32 side.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/clipboard.c       | 68 +++++++++++++++++++++++++++++++++++++++++++
 dlls/user32/tests/clipboard.c |  6 ++--
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c
index 9383fe3..0fe5631 100644
--- a/dlls/user32/clipboard.c
+++ b/dlls/user32/clipboard.c
@@ -140,6 +140,16 @@ static void add_synthesized_text(void)
     }
 }
 
+/* add synthesized metafile formats based on what is already in the clipboard */
+static void add_synthesized_metafile(void)
+{
+    BOOL has_mf = IsClipboardFormatAvailable( CF_METAFILEPICT );
+    BOOL has_emf = IsClipboardFormatAvailable( CF_ENHMETAFILE );
+
+    if (!has_mf && has_emf) add_synthesized_format( CF_METAFILEPICT, CF_ENHMETAFILE );
+    else if (!has_emf && has_mf) add_synthesized_format( CF_ENHMETAFILE, CF_METAFILEPICT );
+}
+
 /* render synthesized ANSI text based on the contents of the 'from' format */
 static HANDLE render_synthesized_textA( HANDLE data, UINT format, UINT from )
 {
@@ -190,6 +200,57 @@ static HANDLE render_synthesized_textW( HANDLE data, UINT from )
     return ret;
 }
 
+/* render a synthesized metafile based on the enhmetafile clipboard data */
+static HANDLE render_synthesized_metafile( HANDLE data )
+{
+    HANDLE ret = 0;
+    UINT size;
+    void *bits;
+    METAFILEPICT *pict;
+    ENHMETAHEADER header;
+    HDC hdc = GetDC( 0 );
+
+    size = GetWinMetaFileBits( data, 0, NULL, MM_ISOTROPIC, hdc );
+    if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
+    {
+        if (GetEnhMetaFileHeader( data, sizeof(header), &header ) &&
+            GetWinMetaFileBits( data, size, bits, MM_ISOTROPIC, hdc ))
+        {
+            if ((ret = GlobalAlloc( GMEM_FIXED, sizeof(*pict) )))
+            {
+                pict = (METAFILEPICT *)ret;
+                pict->mm   = MM_ISOTROPIC;
+                pict->xExt = header.rclFrame.right - header.rclFrame.left;
+                pict->yExt = header.rclFrame.bottom - header.rclFrame.top;
+                pict->hMF  = SetMetaFileBitsEx( size, bits );
+            }
+        }
+        HeapFree( GetProcessHeap(), 0, bits );
+    }
+    ReleaseDC( 0, hdc );
+    return ret;
+}
+
+/* render a synthesized enhmetafile based on the metafile clipboard data */
+static HANDLE render_synthesized_enhmetafile( HANDLE data )
+{
+    METAFILEPICT *pict;
+    HANDLE ret = 0;
+    UINT size;
+    void *bits;
+
+    if (!(pict = GlobalLock( data ))) return 0;
+
+    size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
+    if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
+    {
+        GetMetaFileBitsEx( pict->hMF, size, bits );
+        ret = SetWinMetaFileBits( size, bits, NULL, pict );
+        HeapFree( GetProcessHeap(), 0, bits );
+    }
+    return ret;
+}
+
 /* render a synthesized format */
 static HANDLE render_synthesized_format( UINT format, UINT from )
 {
@@ -207,6 +268,12 @@ static HANDLE render_synthesized_format( UINT format, UINT from )
     case CF_UNICODETEXT:
         data = render_synthesized_textW( data, from );
         break;
+    case CF_METAFILEPICT:
+        data = render_synthesized_metafile( data );
+        break;
+    case CF_ENHMETAFILE:
+        data = render_synthesized_enhmetafile( data );
+        break;
     default:
         assert( 0 );
     }
@@ -338,6 +405,7 @@ BOOL WINAPI CloseClipboard(void)
     {
         memset( synthesized_formats, 0, sizeof(synthesized_formats) );
         add_synthesized_text();
+        add_synthesized_metafile();
     }
 
     SERVER_START_REQ( close_clipboard )
diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c
index c674c9d..4c00361 100644
--- a/dlls/user32/tests/clipboard.c
+++ b/dlls/user32/tests/clipboard.c
@@ -665,7 +665,7 @@ static void test_synthesized(void)
     cf = EnumClipboardFormats(cf);
     ok(cf == CF_METAFILEPICT, "cf %08x\n", cf);
     data = GetClipboardData(cf);
-    todo_wine ok(data != NULL, "couldn't get data, cf %08x\n", cf);
+    ok(data != NULL, "couldn't get data, cf %08x\n", cf);
 
     cf = EnumClipboardFormats(cf);
     ok(cf == 0, "cf %08x\n", cf);
@@ -756,7 +756,6 @@ static void test_synthesized(void)
                i, j, cf, tests[i].expected[j] );
             if (cf != tests[i].expected[j]) break;
             data = GetClipboardData( cf );
-            todo_wine_if (j && cf == CF_METAFILEPICT)
             ok(data != NULL ||
                broken( tests[i].format == CF_DIBV5 && cf == CF_DIB ), /* >= Vista */
                "%u: couldn't get data, cf %04x err %d\n", i, cf, GetLastError());
@@ -830,13 +829,12 @@ static void test_synthesized(void)
             else
             {
                 ok(!data, "%u: format %04x got data %p\n", i, cf, data);
-                todo_wine_if( tests[i].format == CF_ENHMETAFILE && tests[i].expected[j] == CF_METAFILEPICT )
                 ok( rendered == (1 << tests[i].format),
                     "%u.%u: formats %08x have been rendered\n", i, j, rendered );
                 /* try to render a second time */
                 data = GetClipboardData( cf );
                 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
-                todo_wine_if( i > 2 && j == 1 )
+                todo_wine_if( i > 4 && j == 1 )
                 ok( rendered == (1 << tests[i].format),
                     "%u.%u: formats %08x have been rendered\n", i, j, rendered );
             }




More information about the wine-cvs mailing list