From: Jactry Zeng jzeng@codeweavers.com
Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/user32/tests/clipboard.c | 79 ++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c index 3053de398f9..c2e360bc26d 100644 --- a/dlls/user32/tests/clipboard.c +++ b/dlls/user32/tests/clipboard.c @@ -1897,10 +1897,14 @@ static void test_data_handles(void) { BOOL r; char *ptr; - HANDLE h, text; + HANDLE h, text, metafile; HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL ); BITMAPINFO bmi; void *bits; + PALETTEENTRY entry; + BYTE buffer[1024]; + HENHMETAFILE emf; + int result;
ok( hwnd != 0, "window creation failed\n" ); format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" ); @@ -2013,6 +2017,79 @@ static void test_data_handles(void) r = CloseClipboard(); ok( r, "gle %ld\n", GetLastError() );
+ r = open_clipboard( hwnd ); + ok( r, "Open clipboard failed: %#lx.\n", GetLastError() ); + r = EmptyClipboard(); + ok( r, "EmptyClipboard failed: %#lx.\n", GetLastError() ); + + bitmap = CreateBitmap( 10, 10, 1, 1, NULL ); + h = SetClipboardData( CF_BITMAP, bitmap ); + ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h ); + ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" ); + h = GetClipboardData( CF_BITMAP ); + ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h ); + memset( &bmi, 0, sizeof(bmi) ); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + result = GetDIBits( GetDC( 0 ), h, 0, 0, NULL, &bmi, 0 ); + todo_wine ok( !!result && result != ERROR_INVALID_PARAMETER, "GetDIBits failed: %#lx.\n", GetLastError() ); + + bitmap = CreateBitmap( 10, 10, 1, 1, NULL ); + h = SetClipboardData( CF_DSPBITMAP, bitmap ); + ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h ); + ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" ); + h = GetClipboardData( CF_DSPBITMAP ); + ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h ); + memset( &bmi, 0, sizeof(bmi) ); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + ok( !GetDIBits( GetDC( 0 ), h, 0, 0, 0, &bmi, 0 ), "GetDIBits returned unexpected value.\n" ); + + palette = CreatePalette( &logpalette ); + h = SetClipboardData( CF_PALETTE, palette ); + ok( h == palette, "Expected palette %p, got %p.\n", palette, h ); + ok( !!DeleteObject( palette ), "DeleteObject failed.\n" ); + h = GetClipboardData( CF_PALETTE ); + ok( h == palette, "Expected palette %p, got %p.\n", palette, h ); + todo_wine ok( !!GetPaletteEntries( h, 0, 1, &entry ), "GetPaletteEntries %p failed.\n", h ); + todo_wine ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56, + "Got wrong color (%02x, %02x, %02x).\n", entry.peRed, entry.peGreen, entry.peBlue ); + + emf = create_emf(); + h = SetClipboardData( CF_ENHMETAFILE, emf ); + ok( h == emf, "Expected enhmetafile %p, got %p.\n", palette, h ); + ok( !!DeleteEnhMetaFile( emf ), "DeleteEnhMetaFile failed.\n" ); + h = GetClipboardData( CF_ENHMETAFILE ); + ok( h == emf, "Expected enhmetafile %p, got %p.\n", palette, h ); + ok( !GetEnhMetaFileBits( h, sizeof(buffer), buffer ), "GetEnhMetaFileBits returned unexpected value.\n" ); + + emf = create_emf(); + h = SetClipboardData( CF_DSPENHMETAFILE, emf ); + ok( h == emf, "Expected enhmetafile %p, got %p.\n", emf, h ); + ok( !!DeleteEnhMetaFile( emf ), "DeleteEnhMetaFile failed.\n" ); + h = GetClipboardData( CF_DSPENHMETAFILE ); + ok( h == emf, "Expected enhmetafile %p, got %p.\n", emf, h ); + ok( !GetEnhMetaFileBits( h, sizeof(buffer), buffer ), "GetEnhMetaFileBits returned unexpected value.\n" ); + + metafile = create_metafile(); + h = SetClipboardData( CF_METAFILEPICT, metafile ); + ok( h == metafile, "Expected metafilepict %p, got %p.\n", metafile, h ); + ok( !GlobalFree( metafile ), "GlobalFree failed.\n" ); + h = GetClipboardData( CF_METAFILEPICT ); + ok( h == metafile, "Expected metafile %p, got %p.\n", metafile, h ); + ok( is_freed( h ), "Expected freed mem %p.\n", h ); + + metafile = create_metafile(); + h = SetClipboardData( CF_DSPMETAFILEPICT, metafile ); + ok( h == metafile, "Expected metafilepict %p, got %p.\n", metafile, h ); + ok( !GlobalFree( metafile ), "GlobalFree failed.\n" ); + h = GetClipboardData( CF_DSPMETAFILEPICT ); + ok( h == metafile, "Expected metafile %p, got %p.\n", metafile, h ); + ok( is_freed( h ), "Expected freed mem %p.\n", h ); + + r = EmptyClipboard(); + ok( r, "EmptyClipboard failed: %#lx.\n", GetLastError() ); + r = CloseClipboard(); + ok( r, "CloseClipboard failed: %#lx.\n", GetLastError() ); + DestroyWindow( hwnd ); }
From: Jactry Zeng jzeng@codeweavers.com
Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/user32/tests/clipboard.c | 6 +++--- dlls/win32u/clipboard.c | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c index c2e360bc26d..53a54d52ab0 100644 --- a/dlls/user32/tests/clipboard.c +++ b/dlls/user32/tests/clipboard.c @@ -2031,7 +2031,7 @@ static void test_data_handles(void) memset( &bmi, 0, sizeof(bmi) ); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); result = GetDIBits( GetDC( 0 ), h, 0, 0, NULL, &bmi, 0 ); - todo_wine ok( !!result && result != ERROR_INVALID_PARAMETER, "GetDIBits failed: %#lx.\n", GetLastError() ); + ok( !!result && result != ERROR_INVALID_PARAMETER, "GetDIBits failed: %#lx.\n", GetLastError() );
bitmap = CreateBitmap( 10, 10, 1, 1, NULL ); h = SetClipboardData( CF_DSPBITMAP, bitmap ); @@ -2049,8 +2049,8 @@ static void test_data_handles(void) ok( !!DeleteObject( palette ), "DeleteObject failed.\n" ); h = GetClipboardData( CF_PALETTE ); ok( h == palette, "Expected palette %p, got %p.\n", palette, h ); - todo_wine ok( !!GetPaletteEntries( h, 0, 1, &entry ), "GetPaletteEntries %p failed.\n", h ); - todo_wine ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56, + ok( !!GetPaletteEntries( h, 0, 1, &entry ), "GetPaletteEntries %p failed.\n", h ); + ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56, "Got wrong color (%02x, %02x, %02x).\n", entry.peRed, entry.peGreen, entry.peBlue );
emf = create_emf(); diff --git a/dlls/win32u/clipboard.c b/dlls/win32u/clipboard.c index 67bdd0ba391..0ddbc62f444 100644 --- a/dlls/win32u/clipboard.c +++ b/dlls/win32u/clipboard.c @@ -31,6 +31,7 @@ #include "ntstatus.h" #define WIN32_NO_STATUS #include "win32u_private.h" +#include "ntgdi_private.h" #include "ntuser_private.h" #include "wine/server.h" #include "wine/debug.h" @@ -112,8 +113,9 @@ static void free_cached_data( struct cached_format *cache ) switch (cache->format) { case CF_BITMAP: - case CF_DSPBITMAP: case CF_PALETTE: + make_gdi_object_system( cache->handle, FALSE ); + case CF_DSPBITMAP: NtGdiDeleteObjectApp( cache->handle ); break;
@@ -595,6 +597,11 @@ NTSTATUS WINAPI NtUserSetClipboardData( UINT format, HANDLE data, struct set_cli cache->format = format; cache->handle = data; } + + if (format == CF_BITMAP || format == CF_PALETTE) + { + make_gdi_object_system( cache->handle, TRUE ); + } }
pthread_mutex_lock( &clipboard_mutex );
Huw Davies (@huw) commented about dlls/user32/tests/clipboard.c:
ok( r, "gle %ld\n", GetLastError() );
- r = open_clipboard( hwnd );
- ok( r, "Open clipboard failed: %#lx.\n", GetLastError() );
- r = EmptyClipboard();
- ok( r, "EmptyClipboard failed: %#lx.\n", GetLastError() );
- bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
- h = SetClipboardData( CF_BITMAP, bitmap );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" );
- h = GetClipboardData( CF_BITMAP );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- memset( &bmi, 0, sizeof(bmi) );
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- result = GetDIBits( GetDC( 0 ), h, 0, 0, NULL, &bmi, 0 );
You're leaking a dc here. It's probably better to call `GetDC()` at the start of the function and `ReleaseDC()` at the end.
Huw Davies (@huw) commented about dlls/user32/tests/clipboard.c:
- r = open_clipboard( hwnd );
- ok( r, "Open clipboard failed: %#lx.\n", GetLastError() );
- r = EmptyClipboard();
- ok( r, "EmptyClipboard failed: %#lx.\n", GetLastError() );
- bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
- h = SetClipboardData( CF_BITMAP, bitmap );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" );
- h = GetClipboardData( CF_BITMAP );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- memset( &bmi, 0, sizeof(bmi) );
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- result = GetDIBits( GetDC( 0 ), h, 0, 0, NULL, &bmi, 0 );
- todo_wine ok( !!result && result != ERROR_INVALID_PARAMETER, "GetDIBits failed: %#lx.\n", GetLastError() );
I doubt `GetDIBits()` returns `ERROR_INVALID_PARAMETER`, that's likely a mistake in msdn and probably refers to the result of calling `GetLastError()`. Just testing for a non-zero return should be fine.
Huw Davies (@huw) commented about dlls/user32/tests/clipboard.c:
- h = GetClipboardData( CF_BITMAP );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- memset( &bmi, 0, sizeof(bmi) );
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- result = GetDIBits( GetDC( 0 ), h, 0, 0, NULL, &bmi, 0 );
- todo_wine ok( !!result && result != ERROR_INVALID_PARAMETER, "GetDIBits failed: %#lx.\n", GetLastError() );
- bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
- h = SetClipboardData( CF_DSPBITMAP, bitmap );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" );
- h = GetClipboardData( CF_DSPBITMAP );
- ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
- memset( &bmi, 0, sizeof(bmi) );
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- ok( !GetDIBits( GetDC( 0 ), h, 0, 0, 0, &bmi, 0 ), "GetDIBits returned unexpected value.\n" );
Ok, so Windows really does something different for CF_BITMAP as opposed to CF_DSPBITMAP, interesting.