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