user32: Synthesize metafile clipboard formats on the user32 side.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-09-07 10:51:21 +09:00
parent 686369022d
commit 1993898459
2 changed files with 70 additions and 4 deletions

View File

@ -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 )

View File

@ -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 );
}