1c2c66affSColin Finck /* 2c2c66affSColin Finck * Unit test suite for clipboard functions. 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 2002 Dmitry Timoshkov 5c2c66affSColin Finck * 6c2c66affSColin Finck * This library is free software; you can redistribute it and/or 7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 8c2c66affSColin Finck * License as published by the Free Software Foundation; either 9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 10c2c66affSColin Finck * 11c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14c2c66affSColin Finck * Lesser General Public License for more details. 15c2c66affSColin Finck * 16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 17c2c66affSColin Finck * License along with this library; if not, write to the Free Software 18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19c2c66affSColin Finck */ 20c2c66affSColin Finck 21*d558fc75SAmine Khaldi #include <stdio.h> 22*d558fc75SAmine Khaldi #include "wine/test.h" 23*d558fc75SAmine Khaldi #include "winbase.h" 24*d558fc75SAmine Khaldi #include "winerror.h" 25*d558fc75SAmine Khaldi #include "wingdi.h" 26*d558fc75SAmine Khaldi #include "winuser.h" 27*d558fc75SAmine Khaldi #include "winnls.h" 28c2c66affSColin Finck 29*d558fc75SAmine Khaldi #ifdef __REACTOS__ 30c2c66affSColin Finck #define WM_CLIPBOARDUPDATE 0x031D 31*d558fc75SAmine Khaldi #endif 32c2c66affSColin Finck 33c2c66affSColin Finck static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd); 34c2c66affSColin Finck static BOOL (WINAPI *pRemoveClipboardFormatListener)(HWND hwnd); 35c2c66affSColin Finck static BOOL (WINAPI *pGetUpdatedClipboardFormats)( UINT *formats, UINT count, UINT *out_count ); 36c2c66affSColin Finck 37c2c66affSColin Finck static int thread_from_line; 38c2c66affSColin Finck static char *argv0; 39c2c66affSColin Finck 40c2c66affSColin Finck static DWORD WINAPI open_clipboard_thread(LPVOID arg) 41c2c66affSColin Finck { 42c2c66affSColin Finck HWND hWnd = arg; 43c2c66affSColin Finck ok(OpenClipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line); 44c2c66affSColin Finck return 0; 45c2c66affSColin Finck } 46c2c66affSColin Finck 47c2c66affSColin Finck static DWORD WINAPI empty_clipboard_thread(LPVOID arg) 48c2c66affSColin Finck { 49c2c66affSColin Finck SetLastError( 0xdeadbeef ); 50c2c66affSColin Finck ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line ); 51c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", 52c2c66affSColin Finck thread_from_line, GetLastError()); 53c2c66affSColin Finck return 0; 54c2c66affSColin Finck } 55c2c66affSColin Finck 56c2c66affSColin Finck static DWORD WINAPI open_and_empty_clipboard_thread(LPVOID arg) 57c2c66affSColin Finck { 58c2c66affSColin Finck HWND hWnd = arg; 59c2c66affSColin Finck ok(OpenClipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line); 60c2c66affSColin Finck ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line ); 61c2c66affSColin Finck return 0; 62c2c66affSColin Finck } 63c2c66affSColin Finck 64c2c66affSColin Finck static DWORD WINAPI open_and_empty_clipboard_win_thread(LPVOID arg) 65c2c66affSColin Finck { 66c2c66affSColin Finck HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL ); 67c2c66affSColin Finck ok(OpenClipboard(hwnd), "%u: OpenClipboard failed\n", thread_from_line); 68c2c66affSColin Finck ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line ); 69c2c66affSColin Finck return 0; 70c2c66affSColin Finck } 71c2c66affSColin Finck 72c2c66affSColin Finck static DWORD WINAPI set_clipboard_data_thread(LPVOID arg) 73c2c66affSColin Finck { 74c2c66affSColin Finck HWND hwnd = arg; 75c2c66affSColin Finck HANDLE ret; 76c2c66affSColin Finck 77c2c66affSColin Finck SetLastError( 0xdeadbeef ); 78c2c66affSColin Finck if (GetClipboardOwner() == hwnd) 79c2c66affSColin Finck { 80c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 ); 81c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData failed\n", thread_from_line ); 82c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); 83c2c66affSColin Finck ok( ret != 0, "%u: SetClipboardData failed err %u\n", thread_from_line, GetLastError() ); 84c2c66affSColin Finck SetLastError( 0xdeadbeef ); 85c2c66affSColin Finck ret = GetClipboardData( CF_WAVE ); 86c2c66affSColin Finck ok( !ret, "%u: GetClipboardData succeeded\n", thread_from_line ); 87c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", 88c2c66affSColin Finck thread_from_line, GetLastError()); 89c2c66affSColin Finck } 90c2c66affSColin Finck else 91c2c66affSColin Finck { 92c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 ); 93c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", 94c2c66affSColin Finck thread_from_line, GetLastError()); 95c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line ); 96c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); 97c2c66affSColin Finck ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line ); 98c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", 99c2c66affSColin Finck thread_from_line, GetLastError()); 100c2c66affSColin Finck } 101c2c66affSColin Finck return 0; 102c2c66affSColin Finck } 103c2c66affSColin Finck 104c2c66affSColin Finck static void set_clipboard_data_process( int arg ) 105c2c66affSColin Finck { 106c2c66affSColin Finck HANDLE ret; 107c2c66affSColin Finck 108c2c66affSColin Finck SetLastError( 0xdeadbeef ); 109c2c66affSColin Finck if (arg) 110c2c66affSColin Finck { 111c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "process %u: CF_WAVE not available\n", arg ); 112c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); 113c2c66affSColin Finck ok( ret != 0, "process %u: SetClipboardData failed err %u\n", arg, GetLastError() ); 114c2c66affSColin Finck } 115c2c66affSColin Finck else 116c2c66affSColin Finck { 117c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 ); 118c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n", 119c2c66affSColin Finck arg, GetLastError()); 120c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "process %u: SetClipboardData succeeded\n", arg ); 121c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); 122c2c66affSColin Finck ok( !ret, "process %u: SetClipboardData succeeded\n", arg ); 123c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n", 124c2c66affSColin Finck arg, GetLastError()); 125c2c66affSColin Finck } 126c2c66affSColin Finck } 127c2c66affSColin Finck 128c2c66affSColin Finck static void grab_clipboard_process( int arg ) 129c2c66affSColin Finck { 130c2c66affSColin Finck BOOL ret; 131c2c66affSColin Finck 132c2c66affSColin Finck SetLastError( 0xdeadbeef ); 133c2c66affSColin Finck ret = OpenClipboard( 0 ); 134c2c66affSColin Finck ok( ret, "OpenClipboard failed\n" ); 135c2c66affSColin Finck ret = EmptyClipboard(); 136c2c66affSColin Finck ok( ret, "EmptyClipboard failed\n" ); 137c2c66affSColin Finck if (arg) 138c2c66affSColin Finck { 139c2c66affSColin Finck HANDLE ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); 140c2c66affSColin Finck ok( ret != 0, "process %u: SetClipboardData failed err %u\n", arg, GetLastError() ); 141c2c66affSColin Finck } 142c2c66affSColin Finck } 143c2c66affSColin Finck 144c2c66affSColin Finck static void run_thread( LPTHREAD_START_ROUTINE func, void *arg, int line ) 145c2c66affSColin Finck { 146c2c66affSColin Finck DWORD ret; 147c2c66affSColin Finck HANDLE thread; 148c2c66affSColin Finck 149c2c66affSColin Finck thread_from_line = line; 150c2c66affSColin Finck thread = CreateThread(NULL, 0, func, arg, 0, NULL); 151c2c66affSColin Finck ok(thread != NULL, "%u: CreateThread failed with error %d\n", line, GetLastError()); 152c2c66affSColin Finck for (;;) 153c2c66affSColin Finck { 154c2c66affSColin Finck ret = MsgWaitForMultipleObjectsEx( 1, &thread, 1000, QS_ALLINPUT, 0 ); 155c2c66affSColin Finck if (ret == WAIT_OBJECT_0 + 1) 156c2c66affSColin Finck { 157c2c66affSColin Finck MSG msg; 158c2c66affSColin Finck while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); 159c2c66affSColin Finck } 160c2c66affSColin Finck else break; 161c2c66affSColin Finck } 162c2c66affSColin Finck ok(ret == WAIT_OBJECT_0, "%u: expected WAIT_OBJECT_0, got %u\n", line, ret); 163c2c66affSColin Finck CloseHandle(thread); 164c2c66affSColin Finck } 165c2c66affSColin Finck 166c2c66affSColin Finck static void run_process( const char *args ) 167c2c66affSColin Finck { 168c2c66affSColin Finck char cmd[MAX_PATH]; 169c2c66affSColin Finck PROCESS_INFORMATION info; 170c2c66affSColin Finck STARTUPINFOA startup; 171c2c66affSColin Finck 172c2c66affSColin Finck sprintf( cmd, "%s clipboard %s", argv0, args ); 173c2c66affSColin Finck memset( &startup, 0, sizeof(startup) ); 174c2c66affSColin Finck startup.cb = sizeof(startup); 175c2c66affSColin Finck ok( CreateProcessA( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ), 176c2c66affSColin Finck "CreateProcess %s failed\n", cmd ); 177c2c66affSColin Finck 178c2c66affSColin Finck winetest_wait_child_process( info.hProcess ); 179c2c66affSColin Finck CloseHandle( info.hProcess ); 180c2c66affSColin Finck CloseHandle( info.hThread ); 181c2c66affSColin Finck } 182c2c66affSColin Finck 183c2c66affSColin Finck static WNDPROC old_proc; 184c2c66affSColin Finck static LRESULT CALLBACK winproc_wrapper( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) 185c2c66affSColin Finck { 186c2c66affSColin Finck static int wm_renderallformats; 187c2c66affSColin Finck static int wm_drawclipboard; 188c2c66affSColin Finck static int seqno; 189c2c66affSColin Finck DWORD msg_flags = InSendMessageEx( NULL ); 190c2c66affSColin Finck 191c2c66affSColin Finck if (!seqno) seqno = GetClipboardSequenceNumber(); 192c2c66affSColin Finck 193c2c66affSColin Finck trace( "%p msg %04x\n", hwnd, msg ); 194c2c66affSColin Finck if (!wm_renderallformats) 195c2c66affSColin Finck { 196c2c66affSColin Finck ok( GetClipboardOwner() == hwnd, "%04x: wrong owner %p/%p\n", msg, GetClipboardOwner(), hwnd ); 197c2c66affSColin Finck ok( seqno == GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg ); 198c2c66affSColin Finck } 199c2c66affSColin Finck else 200c2c66affSColin Finck { 201c2c66affSColin Finck ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg, GetClipboardOwner() ); 202c2c66affSColin Finck ok( seqno + 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg ); 203c2c66affSColin Finck } 204c2c66affSColin Finck ok( GetClipboardViewer() == hwnd, "%04x: wrong viewer %p/%p\n", msg, GetClipboardViewer(), hwnd ); 205c2c66affSColin Finck ok( GetOpenClipboardWindow() == hwnd, "%04x: wrong open win %p/%p\n", 206c2c66affSColin Finck msg, GetOpenClipboardWindow(), hwnd ); 207c2c66affSColin Finck 208c2c66affSColin Finck switch (msg) 209c2c66affSColin Finck { 210c2c66affSColin Finck case WM_DESTROY: 211c2c66affSColin Finck ok( wm_renderallformats, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" ); 212c2c66affSColin Finck ok( wm_drawclipboard, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" ); 213c2c66affSColin Finck break; 214c2c66affSColin Finck case WM_DRAWCLIPBOARD: 215c2c66affSColin Finck ok( msg_flags == ISMEX_NOSEND, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags ); 216c2c66affSColin Finck wm_drawclipboard++; 217c2c66affSColin Finck break; 218c2c66affSColin Finck case WM_RENDERALLFORMATS: 219c2c66affSColin Finck ok( msg_flags == ISMEX_NOSEND, "WM_RENDERALLFORMATS wrong flags %x\n", msg_flags ); 220c2c66affSColin Finck wm_renderallformats++; 221c2c66affSColin Finck break; 222c2c66affSColin Finck } 223c2c66affSColin Finck return old_proc( hwnd, msg, wp, lp ); 224c2c66affSColin Finck } 225c2c66affSColin Finck 226c2c66affSColin Finck static void test_ClipboardOwner(void) 227c2c66affSColin Finck { 228c2c66affSColin Finck HWND hWnd1, hWnd2; 229c2c66affSColin Finck BOOL ret; 230c2c66affSColin Finck 231c2c66affSColin Finck SetLastError(0xdeadbeef); 232c2c66affSColin Finck ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, 233c2c66affSColin Finck "could not perform clipboard test: clipboard already owned\n"); 234c2c66affSColin Finck 235c2c66affSColin Finck hWnd1 = CreateWindowExA(0, "static", NULL, WS_POPUP, 236c2c66affSColin Finck 0, 0, 10, 10, 0, 0, 0, NULL); 237c2c66affSColin Finck ok(hWnd1 != 0, "CreateWindowExA error %d\n", GetLastError()); 238c2c66affSColin Finck trace("hWnd1 = %p\n", hWnd1); 239c2c66affSColin Finck 240c2c66affSColin Finck hWnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP, 241c2c66affSColin Finck 0, 0, 10, 10, 0, 0, 0, NULL); 242c2c66affSColin Finck ok(hWnd2 != 0, "CreateWindowExA error %d\n", GetLastError()); 243c2c66affSColin Finck trace("hWnd2 = %p\n", hWnd2); 244c2c66affSColin Finck 245c2c66affSColin Finck SetLastError(0xdeadbeef); 246c2c66affSColin Finck ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n"); 247c2c66affSColin Finck ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */ 248c2c66affSColin Finck "wrong error %u\n", GetLastError()); 249c2c66affSColin Finck 250c2c66affSColin Finck ok(OpenClipboard(0), "OpenClipboard failed\n"); 251c2c66affSColin Finck ok(!GetClipboardOwner(), "clipboard should still be not owned\n"); 252c2c66affSColin Finck ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n"); 253c2c66affSColin Finck ok(OpenClipboard(0), "OpenClipboard again failed\n"); 254c2c66affSColin Finck ret = CloseClipboard(); 255c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError()); 256c2c66affSColin Finck 257c2c66affSColin Finck ok(OpenClipboard(hWnd1), "OpenClipboard failed\n"); 258c2c66affSColin Finck run_thread( open_clipboard_thread, hWnd1, __LINE__ ); 259c2c66affSColin Finck run_thread( empty_clipboard_thread, 0, __LINE__ ); 260c2c66affSColin Finck run_thread( set_clipboard_data_thread, hWnd1, __LINE__ ); 261c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE available\n" ); 262c2c66affSColin Finck ok( !GetClipboardData( CF_WAVE ), "CF_WAVE data available\n" ); 263c2c66affSColin Finck run_process( "set_clipboard_data 0" ); 264c2c66affSColin Finck ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n"); 265c2c66affSColin Finck ok(OpenClipboard(hWnd1), "OpenClipboard failed\n"); 266c2c66affSColin Finck 267c2c66affSColin Finck SetLastError(0xdeadbeef); 268c2c66affSColin Finck ret = OpenClipboard(hWnd2); 269c2c66affSColin Finck ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED), 270c2c66affSColin Finck "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError()); 271c2c66affSColin Finck 272c2c66affSColin Finck SetLastError(0xdeadbeef); 273c2c66affSColin Finck ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n"); 274c2c66affSColin Finck ret = EmptyClipboard(); 275c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError()); 276c2c66affSColin Finck ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner()); 277c2c66affSColin Finck run_thread( empty_clipboard_thread, 0, __LINE__ ); 278c2c66affSColin Finck run_thread( set_clipboard_data_thread, hWnd1, __LINE__ ); 279c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" ); 280c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" ); 281c2c66affSColin Finck run_process( "set_clipboard_data 1" ); 282c2c66affSColin Finck 283c2c66affSColin Finck SetLastError(0xdeadbeef); 284c2c66affSColin Finck ret = OpenClipboard(hWnd2); 285c2c66affSColin Finck ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED), 286c2c66affSColin Finck "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError()); 287c2c66affSColin Finck 288c2c66affSColin Finck ret = CloseClipboard(); 289c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError()); 290c2c66affSColin Finck ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n"); 291c2c66affSColin Finck 292c2c66affSColin Finck /* any window will do, even from a different process */ 293c2c66affSColin Finck ret = OpenClipboard( GetDesktopWindow() ); 294c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError()); 295c2c66affSColin Finck ret = EmptyClipboard(); 296c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError()); 297c2c66affSColin Finck ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n", 298c2c66affSColin Finck GetClipboardOwner(), GetDesktopWindow() ); 299c2c66affSColin Finck run_thread( set_clipboard_data_thread, GetDesktopWindow(), __LINE__ ); 300c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" ); 301c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" ); 302c2c66affSColin Finck run_process( "set_clipboard_data 2" ); 303c2c66affSColin Finck ret = CloseClipboard(); 304c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError()); 305c2c66affSColin Finck 306c2c66affSColin Finck ret = OpenClipboard( hWnd1 ); 307c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError()); 308c2c66affSColin Finck ret = EmptyClipboard(); 309c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError()); 310c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 ); 311c2c66affSColin Finck SetClipboardViewer( hWnd1 ); 312c2c66affSColin Finck ok( GetClipboardOwner() == hWnd1, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1 ); 313c2c66affSColin Finck ok( GetClipboardViewer() == hWnd1, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1 ); 314c2c66affSColin Finck ok( GetOpenClipboardWindow() == hWnd1, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1 ); 315c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" ); 316c2c66affSColin Finck 317c2c66affSColin Finck old_proc = (WNDPROC)SetWindowLongPtrA( hWnd1, GWLP_WNDPROC, (LONG_PTR)winproc_wrapper ); 318c2c66affSColin Finck ret = DestroyWindow(hWnd1); 319c2c66affSColin Finck ok( ret, "DestroyWindow error %d\n", GetLastError()); 320c2c66affSColin Finck ret = DestroyWindow(hWnd2); 321c2c66affSColin Finck ok( ret, "DestroyWindow error %d\n", GetLastError()); 322c2c66affSColin Finck SetLastError(0xdeadbeef); 323c2c66affSColin Finck ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n"); 324c2c66affSColin Finck ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n"); 325c2c66affSColin Finck ok(!GetOpenClipboardWindow() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n"); 326c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE available\n" ); 327c2c66affSColin Finck 328c2c66affSColin Finck SetLastError( 0xdeadbeef ); 329c2c66affSColin Finck ret = CloseClipboard(); 330c2c66affSColin Finck ok( !ret, "CloseClipboard succeeded\n" ); 331c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() ); 332c2c66affSColin Finck 333c2c66affSColin Finck ret = OpenClipboard( 0 ); 334c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError()); 335c2c66affSColin Finck run_thread( set_clipboard_data_thread, 0, __LINE__ ); 336c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" ); 337c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" ); 338c2c66affSColin Finck run_process( "set_clipboard_data 3" ); 339c2c66affSColin Finck ret = CloseClipboard(); 340c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError()); 341c2c66affSColin Finck 342c2c66affSColin Finck run_thread( open_and_empty_clipboard_thread, 0, __LINE__ ); 343c2c66affSColin Finck ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() ); 344c2c66affSColin Finck ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() ); 345c2c66affSColin Finck 346c2c66affSColin Finck ret = OpenClipboard( 0 ); 347c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError()); 348c2c66affSColin Finck run_thread( set_clipboard_data_thread, 0, __LINE__ ); 349c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" ); 350c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" ); 351c2c66affSColin Finck run_process( "set_clipboard_data 4" ); 352c2c66affSColin Finck ret = EmptyClipboard(); 353c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError()); 354c2c66affSColin Finck ret = CloseClipboard(); 355c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError()); 356c2c66affSColin Finck 357c2c66affSColin Finck SetLastError( 0xdeadbeef ); 358c2c66affSColin Finck ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )), 359c2c66affSColin Finck "SetClipboardData succeeded\n" ); 360c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() ); 361c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" ); 362c2c66affSColin Finck 363c2c66affSColin Finck run_thread( open_and_empty_clipboard_thread, GetDesktopWindow(), __LINE__ ); 364c2c66affSColin Finck ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() ); 365c2c66affSColin Finck ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n", 366c2c66affSColin Finck GetClipboardOwner(), GetDesktopWindow() ); 367c2c66affSColin Finck 368c2c66affSColin Finck run_thread( open_and_empty_clipboard_win_thread, 0, __LINE__ ); 369c2c66affSColin Finck ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() ); 370c2c66affSColin Finck ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() ); 371c2c66affSColin Finck } 372c2c66affSColin Finck 373c2c66affSColin Finck static void test_RegisterClipboardFormatA(void) 374c2c66affSColin Finck { 375c2c66affSColin Finck ATOM atom_id; 376c2c66affSColin Finck UINT format_id, format_id2; 377c2c66affSColin Finck char buf[256]; 378c2c66affSColin Finck int len; 379c2c66affSColin Finck BOOL ret; 380c2c66affSColin Finck HANDLE handle; 381c2c66affSColin Finck 382c2c66affSColin Finck format_id = RegisterClipboardFormatA("my_cool_clipboard_format"); 383c2c66affSColin Finck ok(format_id > 0xc000 && format_id < 0xffff, "invalid clipboard format id %04x\n", format_id); 384c2c66affSColin Finck 385c2c66affSColin Finck format_id2 = RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT"); 386c2c66affSColin Finck ok(format_id2 == format_id, "invalid clipboard format id %04x\n", format_id2); 387c2c66affSColin Finck 388c2c66affSColin Finck len = GetClipboardFormatNameA(format_id, buf, 256); 389c2c66affSColin Finck ok(len == lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len); 390c2c66affSColin Finck ok(!lstrcmpA(buf, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf); 391c2c66affSColin Finck 392*d558fc75SAmine Khaldi len = GetClipboardFormatNameA(format_id, NULL, 0); 393*d558fc75SAmine Khaldi ok(len == 0, "wrong format name length %d\n", len); 394*d558fc75SAmine Khaldi 395c2c66affSColin Finck lstrcpyA(buf, "foo"); 396c2c66affSColin Finck SetLastError(0xdeadbeef); 397c2c66affSColin Finck len = GetAtomNameA((ATOM)format_id, buf, 256); 398c2c66affSColin Finck ok(len == 0, "GetAtomNameA should fail\n"); 399c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "err %d\n", GetLastError()); 400c2c66affSColin Finck 401c2c66affSColin Finck todo_wine 402c2c66affSColin Finck { 403c2c66affSColin Finck lstrcpyA(buf, "foo"); 404c2c66affSColin Finck SetLastError(0xdeadbeef); 405c2c66affSColin Finck len = GlobalGetAtomNameA((ATOM)format_id, buf, 256); 406c2c66affSColin Finck ok(len == 0, "GlobalGetAtomNameA should fail\n"); 407c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "err %d\n", GetLastError()); 408c2c66affSColin Finck } 409c2c66affSColin Finck 410c2c66affSColin Finck SetLastError(0xdeadbeef); 411c2c66affSColin Finck atom_id = FindAtomA("my_cool_clipboard_format"); 412c2c66affSColin Finck ok(atom_id == 0, "FindAtomA should fail\n"); 413c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %d\n", GetLastError()); 414c2c66affSColin Finck 415c2c66affSColin Finck if (0) 416c2c66affSColin Finck { 417c2c66affSColin Finck /* this relies on the clipboard and global atom table being different */ 418c2c66affSColin Finck SetLastError(0xdeadbeef); 419c2c66affSColin Finck atom_id = GlobalFindAtomA("my_cool_clipboard_format"); 420c2c66affSColin Finck ok(atom_id == 0, "GlobalFindAtomA should fail\n"); 421c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %d\n", GetLastError()); 422c2c66affSColin Finck } 423c2c66affSColin Finck 424c2c66affSColin Finck for (format_id = 0; format_id < 0x10fff; format_id++) 425c2c66affSColin Finck { 426c2c66affSColin Finck SetLastError(0xdeadbeef); 427c2c66affSColin Finck len = GetClipboardFormatNameA(format_id, buf, 256); 428c2c66affSColin Finck 429c2c66affSColin Finck if (format_id < 0xc000 || format_id > 0xffff) 430c2c66affSColin Finck ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf); 431c2c66affSColin Finck else if (len && winetest_debug > 1) 432c2c66affSColin Finck trace("%04x: %s\n", format_id, len ? buf : ""); 433c2c66affSColin Finck } 434c2c66affSColin Finck 435c2c66affSColin Finck ret = OpenClipboard(0); 436c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError()); 437c2c66affSColin Finck 438c2c66affSColin Finck /* try some invalid/unregistered formats */ 439c2c66affSColin Finck SetLastError( 0xdeadbeef ); 440c2c66affSColin Finck handle = SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 )); 441c2c66affSColin Finck ok( !handle, "SetClipboardData succeeded\n" ); 442c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError()); 443c2c66affSColin Finck handle = SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 )); 444c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError()); 445c2c66affSColin Finck handle = SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 )); 446c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError()); 447c2c66affSColin Finck handle = SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 )); 448c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError()); 449c2c66affSColin Finck 450c2c66affSColin Finck ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" ); 451c2c66affSColin Finck ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" ); 452c2c66affSColin Finck ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" ); 453c2c66affSColin Finck ok( !IsClipboardFormatAvailable( 0 ), "format available\n" ); 454c2c66affSColin Finck ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" ); 455c2c66affSColin Finck ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" ); 456c2c66affSColin Finck 457c2c66affSColin Finck trace("# of formats available: %d\n", CountClipboardFormats()); 458c2c66affSColin Finck 459c2c66affSColin Finck format_id = 0; 460c2c66affSColin Finck while ((format_id = EnumClipboardFormats(format_id))) 461c2c66affSColin Finck { 462c2c66affSColin Finck ok(IsClipboardFormatAvailable(format_id), "format %04x was listed as available\n", format_id); 463c2c66affSColin Finck len = GetClipboardFormatNameA(format_id, buf, 256); 464c2c66affSColin Finck trace("%04x: %s\n", format_id, len ? buf : ""); 465c2c66affSColin Finck } 466c2c66affSColin Finck 467c2c66affSColin Finck ret = EmptyClipboard(); 468c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError()); 469c2c66affSColin Finck ret =CloseClipboard(); 470c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError()); 471c2c66affSColin Finck 472c2c66affSColin Finck if (CountClipboardFormats()) 473c2c66affSColin Finck { 474c2c66affSColin Finck SetLastError(0xdeadbeef); 475c2c66affSColin Finck ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n"); 476c2c66affSColin Finck ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, 477c2c66affSColin Finck "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError()); 478c2c66affSColin Finck } 479c2c66affSColin Finck 480c2c66affSColin Finck SetLastError(0xdeadbeef); 481c2c66affSColin Finck ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n"); 482c2c66affSColin Finck ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */ 483c2c66affSColin Finck "Wrong error %u\n", GetLastError()); 484c2c66affSColin Finck 485c2c66affSColin Finck format_id = RegisterClipboardFormatA("#1234"); 486c2c66affSColin Finck ok(format_id == 1234, "invalid clipboard format id %04x\n", format_id); 487c2c66affSColin Finck } 488c2c66affSColin Finck 489c2c66affSColin Finck static HGLOBAL create_textA(void) 490c2c66affSColin Finck { 491c2c66affSColin Finck HGLOBAL h = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, 10); 492c2c66affSColin Finck char *p = GlobalLock(h); 493c2c66affSColin Finck memcpy(p, "test\0\0\0\0\0", 10); 494c2c66affSColin Finck GlobalUnlock(h); 495c2c66affSColin Finck return h; 496c2c66affSColin Finck } 497c2c66affSColin Finck 498c2c66affSColin Finck static HGLOBAL create_textW(void) 499c2c66affSColin Finck { 500c2c66affSColin Finck static const WCHAR testW[] = {'t','e','s','t',0,0,0,0,0,0}; 501c2c66affSColin Finck HGLOBAL h = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, sizeof(testW)); 502c2c66affSColin Finck WCHAR *p = GlobalLock(h); 503c2c66affSColin Finck memcpy(p, testW, sizeof(testW)); 504c2c66affSColin Finck GlobalUnlock(h); 505c2c66affSColin Finck return h; 506c2c66affSColin Finck } 507c2c66affSColin Finck 508c2c66affSColin Finck static HANDLE create_metafile(void) 509c2c66affSColin Finck { 510c2c66affSColin Finck const RECT rect = {0, 0, 100, 100}; 511c2c66affSColin Finck METAFILEPICT *pict; 512c2c66affSColin Finck HANDLE ret; 513c2c66affSColin Finck HMETAFILE mf; 514c2c66affSColin Finck HDC hdc = CreateMetaFileA( NULL ); 515c2c66affSColin Finck ExtTextOutA( hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL ); 516c2c66affSColin Finck mf = CloseMetaFile( hdc ); 517c2c66affSColin Finck ret = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(*pict) ); 518c2c66affSColin Finck pict = GlobalLock( ret ); 519c2c66affSColin Finck pict->mm = MM_TEXT; 520c2c66affSColin Finck pict->xExt = pict->yExt = 100; 521c2c66affSColin Finck pict->hMF = mf; 522c2c66affSColin Finck GlobalUnlock( ret ); 523c2c66affSColin Finck return ret; 524c2c66affSColin Finck } 525c2c66affSColin Finck 526c2c66affSColin Finck static HENHMETAFILE create_emf(void) 527c2c66affSColin Finck { 528c2c66affSColin Finck const RECT rect = {0, 0, 100, 100}; 529c2c66affSColin Finck HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Ole Clipboard Test\0Test\0\0"); 530c2c66affSColin Finck ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL); 531c2c66affSColin Finck return CloseEnhMetaFile(hdc); 532c2c66affSColin Finck } 533c2c66affSColin Finck 534c2c66affSColin Finck static HBITMAP create_bitmap(void) 535c2c66affSColin Finck { 536c2c66affSColin Finck HDC hdc = GetDC( 0 ); 537c2c66affSColin Finck UINT bpp = GetDeviceCaps( hdc, BITSPIXEL ); 538c2c66affSColin Finck ReleaseDC( 0, hdc ); 539c2c66affSColin Finck return CreateBitmap( 10, 10, 1, bpp, NULL ); 540c2c66affSColin Finck } 541c2c66affSColin Finck 542c2c66affSColin Finck static HBITMAP create_dib( BOOL v5 ) 543c2c66affSColin Finck { 544c2c66affSColin Finck HANDLE ret; 545c2c66affSColin Finck BITMAPINFOHEADER *hdr; 546c2c66affSColin Finck 547c2c66affSColin Finck ret = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT, 548c2c66affSColin Finck sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD) + 16 * 16 * 4 ); 549c2c66affSColin Finck hdr = GlobalLock( ret ); 550c2c66affSColin Finck hdr->biSize = v5 ? sizeof(BITMAPV5HEADER) : sizeof(*hdr); 551c2c66affSColin Finck hdr->biWidth = 16; 552c2c66affSColin Finck hdr->biHeight = 16; 553c2c66affSColin Finck hdr->biPlanes = 1; 554c2c66affSColin Finck hdr->biBitCount = 32; 555c2c66affSColin Finck hdr->biCompression = BI_RGB; 556c2c66affSColin Finck if (v5) 557c2c66affSColin Finck { 558c2c66affSColin Finck BITMAPV5HEADER *hdr5 = (BITMAPV5HEADER *)hdr; 559c2c66affSColin Finck hdr5->bV5RedMask = 0x0000ff; 560c2c66affSColin Finck hdr5->bV5GreenMask = 0x00ff00; 561c2c66affSColin Finck hdr5->bV5BlueMask = 0xff0000; 562c2c66affSColin Finck hdr5->bV5AlphaMask = 0xff000000; 563c2c66affSColin Finck } 564c2c66affSColin Finck GlobalUnlock( ret ); 565c2c66affSColin Finck return ret; 566c2c66affSColin Finck } 567c2c66affSColin Finck 568c2c66affSColin Finck static LRESULT CALLBACK renderer_winproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) 569c2c66affSColin Finck { 570c2c66affSColin Finck static UINT rendered; 571c2c66affSColin Finck UINT ret; 572c2c66affSColin Finck 573c2c66affSColin Finck switch (msg) 574c2c66affSColin Finck { 575c2c66affSColin Finck case WM_RENDERFORMAT: 576c2c66affSColin Finck if (wp < 32) rendered |= (1 << wp); 577c2c66affSColin Finck break; 578c2c66affSColin Finck case WM_USER: 579c2c66affSColin Finck ret = rendered; 580c2c66affSColin Finck rendered = 0; 581c2c66affSColin Finck return ret; 582c2c66affSColin Finck } 583c2c66affSColin Finck return DefWindowProcA( hwnd, msg, wp, lp ); 584c2c66affSColin Finck } 585c2c66affSColin Finck 586c2c66affSColin Finck static void test_synthesized(void) 587c2c66affSColin Finck { 588c2c66affSColin Finck static const struct test 589c2c66affSColin Finck { 590c2c66affSColin Finck UINT format; 591c2c66affSColin Finck UINT expected[8]; 592c2c66affSColin Finck } tests[] = 593c2c66affSColin Finck { 594c2c66affSColin Finck /* 0 */ { CF_TEXT, { CF_TEXT, CF_LOCALE, CF_OEMTEXT, CF_UNICODETEXT }}, 595c2c66affSColin Finck { CF_OEMTEXT, { CF_OEMTEXT, CF_LOCALE, CF_TEXT, CF_UNICODETEXT }}, 596c2c66affSColin Finck { CF_UNICODETEXT, { CF_UNICODETEXT, CF_LOCALE, CF_TEXT, CF_OEMTEXT }}, 597c2c66affSColin Finck { CF_ENHMETAFILE, { CF_ENHMETAFILE, CF_METAFILEPICT }}, 598c2c66affSColin Finck { CF_METAFILEPICT, { CF_METAFILEPICT, CF_ENHMETAFILE }}, 599c2c66affSColin Finck /* 5 */ { CF_BITMAP, { CF_BITMAP, CF_DIB, CF_DIBV5 }}, 600c2c66affSColin Finck { CF_DIB, { CF_DIB, CF_BITMAP, CF_DIBV5 }}, 601c2c66affSColin Finck { CF_DIBV5, { CF_DIBV5, CF_BITMAP, CF_DIB }}, 602c2c66affSColin Finck }; 603c2c66affSColin Finck 604c2c66affSColin Finck HGLOBAL h, htext; 605c2c66affSColin Finck HENHMETAFILE emf; 606c2c66affSColin Finck BOOL r; 607c2c66affSColin Finck UINT cf, i, j, count, rendered, seq, old_seq; 608c2c66affSColin Finck HANDLE data; 609c2c66affSColin Finck HWND hwnd; 610c2c66affSColin Finck 611c2c66affSColin Finck hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL ); 612c2c66affSColin Finck SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)renderer_winproc ); 613c2c66affSColin Finck 614c2c66affSColin Finck htext = create_textA(); 615c2c66affSColin Finck emf = create_emf(); 616c2c66affSColin Finck 617c2c66affSColin Finck r = OpenClipboard(NULL); 618c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 619c2c66affSColin Finck r = EmptyClipboard(); 620c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 621c2c66affSColin Finck h = SetClipboardData(CF_TEXT, htext); 622c2c66affSColin Finck ok(h == htext, "got %p\n", h); 623c2c66affSColin Finck h = SetClipboardData(CF_ENHMETAFILE, emf); 624c2c66affSColin Finck ok(h == emf, "got %p\n", h); 625c2c66affSColin Finck r = CloseClipboard(); 626c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 627c2c66affSColin Finck 628c2c66affSColin Finck count = CountClipboardFormats(); 629c2c66affSColin Finck ok( count == 6, "count %u\n", count ); 630c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_TEXT ); 631c2c66affSColin Finck ok( r, "CF_TEXT not available err %d\n", GetLastError()); 632c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_LOCALE ); 633c2c66affSColin Finck ok( r, "CF_LOCALE not available err %d\n", GetLastError()); 634c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_OEMTEXT ); 635c2c66affSColin Finck ok( r, "CF_OEMTEXT not available err %d\n", GetLastError()); 636c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_UNICODETEXT ); 637c2c66affSColin Finck ok( r, "CF_UNICODETEXT not available err %d\n", GetLastError()); 638c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_ENHMETAFILE ); 639c2c66affSColin Finck ok( r, "CF_ENHMETAFILE not available err %d\n", GetLastError()); 640c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_METAFILEPICT ); 641c2c66affSColin Finck ok( r, "CF_METAFILEPICT not available err %d\n", GetLastError()); 642c2c66affSColin Finck 643c2c66affSColin Finck r = OpenClipboard(NULL); 644c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 645c2c66affSColin Finck cf = EnumClipboardFormats(0); 646c2c66affSColin Finck ok(cf == CF_TEXT, "cf %08x\n", cf); 647c2c66affSColin Finck data = GetClipboardData(cf); 648c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf); 649c2c66affSColin Finck 650c2c66affSColin Finck cf = EnumClipboardFormats(cf); 651c2c66affSColin Finck ok(cf == CF_ENHMETAFILE, "cf %08x\n", cf); 652c2c66affSColin Finck data = GetClipboardData(cf); 653c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf); 654c2c66affSColin Finck 655c2c66affSColin Finck cf = EnumClipboardFormats(cf); 656c2c66affSColin Finck ok(cf == CF_LOCALE, "cf %08x\n", cf); 657c2c66affSColin Finck data = GetClipboardData(cf); 658c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf); 659c2c66affSColin Finck 660c2c66affSColin Finck cf = EnumClipboardFormats(cf); 661c2c66affSColin Finck ok(cf == CF_OEMTEXT, "cf %08x\n", cf); 662c2c66affSColin Finck data = GetClipboardData(cf); 663c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf); 664c2c66affSColin Finck 665c2c66affSColin Finck cf = EnumClipboardFormats(cf); 666c2c66affSColin Finck ok(cf == CF_UNICODETEXT, "cf %08x\n", cf); 667c2c66affSColin Finck 668c2c66affSColin Finck cf = EnumClipboardFormats(cf); 669c2c66affSColin Finck ok(cf == CF_METAFILEPICT, "cf %08x\n", cf); 670c2c66affSColin Finck data = GetClipboardData(cf); 671c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf); 672c2c66affSColin Finck 673c2c66affSColin Finck cf = EnumClipboardFormats(cf); 674c2c66affSColin Finck ok(cf == 0, "cf %08x\n", cf); 675c2c66affSColin Finck 676c2c66affSColin Finck r = EmptyClipboard(); 677c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 678c2c66affSColin Finck 679c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, create_textW() ); 680c2c66affSColin Finck SetClipboardData( CF_TEXT, create_textA() ); 681c2c66affSColin Finck SetClipboardData( CF_OEMTEXT, create_textA() ); 682c2c66affSColin Finck r = CloseClipboard(); 683c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 684c2c66affSColin Finck 685c2c66affSColin Finck r = OpenClipboard( NULL ); 686c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 687c2c66affSColin Finck SetLastError( 0xdeadbeef ); 688c2c66affSColin Finck cf = EnumClipboardFormats(0); 689c2c66affSColin Finck ok( cf == CF_UNICODETEXT, "cf %08x\n", cf ); 690c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); 691c2c66affSColin Finck SetLastError( 0xdeadbeef ); 692c2c66affSColin Finck cf = EnumClipboardFormats(cf); 693c2c66affSColin Finck ok( cf == CF_TEXT, "cf %08x\n", cf ); 694c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); 695c2c66affSColin Finck SetLastError( 0xdeadbeef ); 696c2c66affSColin Finck cf = EnumClipboardFormats(cf); 697c2c66affSColin Finck ok( cf == CF_OEMTEXT, "cf %08x\n", cf ); 698c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); 699c2c66affSColin Finck SetLastError( 0xdeadbeef ); 700c2c66affSColin Finck cf = EnumClipboardFormats(cf); 701c2c66affSColin Finck ok( cf == CF_LOCALE, "cf %08x\n", cf ); 702c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); 703c2c66affSColin Finck SetLastError( 0xdeadbeef ); 704c2c66affSColin Finck cf = EnumClipboardFormats( cf ); 705c2c66affSColin Finck ok( cf == 0, "cf %08x\n", cf ); 706c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); 707c2c66affSColin Finck SetLastError( 0xdeadbeef ); 708c2c66affSColin Finck cf = EnumClipboardFormats( 0xdead ); 709c2c66affSColin Finck ok( cf == 0, "cf %08x\n", cf ); 710c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() ); 711c2c66affSColin Finck 712c2c66affSColin Finck r = EmptyClipboard(); 713c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 714c2c66affSColin Finck 715c2c66affSColin Finck r = CloseClipboard(); 716c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 717c2c66affSColin Finck 718c2c66affSColin Finck for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) 719c2c66affSColin Finck { 720c2c66affSColin Finck r = OpenClipboard(NULL); 721c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 722c2c66affSColin Finck r = EmptyClipboard(); 723c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 724c2c66affSColin Finck 725c2c66affSColin Finck switch (tests[i].format) 726c2c66affSColin Finck { 727c2c66affSColin Finck case CF_TEXT: 728c2c66affSColin Finck case CF_OEMTEXT: 729c2c66affSColin Finck SetClipboardData( tests[i].format, create_textA() ); 730c2c66affSColin Finck break; 731c2c66affSColin Finck case CF_UNICODETEXT: 732c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, create_textW() ); 733c2c66affSColin Finck break; 734c2c66affSColin Finck case CF_ENHMETAFILE: 735c2c66affSColin Finck SetClipboardData( CF_ENHMETAFILE, create_emf() ); 736c2c66affSColin Finck break; 737c2c66affSColin Finck case CF_METAFILEPICT: 738c2c66affSColin Finck SetClipboardData( CF_METAFILEPICT, create_metafile() ); 739c2c66affSColin Finck break; 740c2c66affSColin Finck case CF_BITMAP: 741c2c66affSColin Finck SetClipboardData( CF_BITMAP, create_bitmap() ); 742c2c66affSColin Finck break; 743c2c66affSColin Finck case CF_DIB: 744c2c66affSColin Finck case CF_DIBV5: 745c2c66affSColin Finck SetClipboardData( tests[i].format, create_dib( tests[i].format == CF_DIBV5 )); 746c2c66affSColin Finck break; 747c2c66affSColin Finck } 748c2c66affSColin Finck 749c2c66affSColin Finck count = CountClipboardFormats(); 750c2c66affSColin Finck ok( count == 1, "%u: count %u\n", i, count ); 751c2c66affSColin Finck 752c2c66affSColin Finck r = CloseClipboard(); 753c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 754c2c66affSColin Finck 755c2c66affSColin Finck count = CountClipboardFormats(); 756c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++) 757c2c66affSColin Finck { 758c2c66affSColin Finck r = IsClipboardFormatAvailable( tests[i].expected[j] ); 759c2c66affSColin Finck ok( r, "%u: %04x not available\n", i, tests[i].expected[j] ); 760c2c66affSColin Finck } 761c2c66affSColin Finck ok( count == j, "%u: count %u instead of %u\n", i, count, j ); 762c2c66affSColin Finck 763c2c66affSColin Finck r = OpenClipboard( hwnd ); 764c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 765c2c66affSColin Finck cf = 0; 766c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++) 767c2c66affSColin Finck { 768c2c66affSColin Finck cf = EnumClipboardFormats( cf ); 769c2c66affSColin Finck ok(cf == tests[i].expected[j], "%u.%u: got %04x instead of %04x\n", 770c2c66affSColin Finck i, j, cf, tests[i].expected[j] ); 771c2c66affSColin Finck if (cf != tests[i].expected[j]) break; 772c2c66affSColin Finck old_seq = GetClipboardSequenceNumber(); 773c2c66affSColin Finck data = GetClipboardData( cf ); 774c2c66affSColin Finck ok(data != NULL || 775c2c66affSColin Finck broken( tests[i].format == CF_DIBV5 && cf == CF_DIB ), /* >= Vista */ 776c2c66affSColin Finck "%u: couldn't get data, cf %04x err %d\n", i, cf, GetLastError()); 777c2c66affSColin Finck seq = GetClipboardSequenceNumber(); 778c2c66affSColin Finck ok(seq == old_seq, "sequence changed (test %d %d)\n", i, cf); 779c2c66affSColin Finck switch (cf) 780c2c66affSColin Finck { 781c2c66affSColin Finck case CF_LOCALE: 782c2c66affSColin Finck { 783c2c66affSColin Finck UINT *ptr = GlobalLock( data ); 784c2c66affSColin Finck ok( GlobalSize( data ) == sizeof(*ptr), "%u: size %lu\n", i, GlobalSize( data )); 785c2c66affSColin Finck ok( *ptr == GetUserDefaultLCID() || 786c2c66affSColin Finck broken( *ptr == MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT )), 787c2c66affSColin Finck "%u: CF_LOCALE %08x/%08x\n", i, *ptr, GetUserDefaultLCID() ); 788c2c66affSColin Finck GlobalUnlock( data ); 789c2c66affSColin Finck break; 790c2c66affSColin Finck } 791c2c66affSColin Finck case CF_TEXT: 792c2c66affSColin Finck case CF_OEMTEXT: 793c2c66affSColin Finck ok( GlobalSize( data ) == 10, "wrong len %ld\n", GlobalSize( data )); 794c2c66affSColin Finck break; 795c2c66affSColin Finck case CF_UNICODETEXT: 796c2c66affSColin Finck ok( GlobalSize( data ) == 10 * sizeof(WCHAR), "wrong len %ld\n", GlobalSize( data )); 797c2c66affSColin Finck break; 798c2c66affSColin Finck } 799c2c66affSColin Finck } 800c2c66affSColin Finck if (!tests[i].expected[j]) 801c2c66affSColin Finck { 802c2c66affSColin Finck cf = EnumClipboardFormats( cf ); 803c2c66affSColin Finck ok(cf == 0, "%u: cf %04x\n", i, cf); 804c2c66affSColin Finck } 805c2c66affSColin Finck 806c2c66affSColin Finck /* now with delayed rendering */ 807c2c66affSColin Finck 808c2c66affSColin Finck r = EmptyClipboard(); 809c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 810c2c66affSColin Finck 811c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 812c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered ); 813c2c66affSColin Finck 814c2c66affSColin Finck SetClipboardData( tests[i].format, 0 ); 815c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 816c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered ); 817c2c66affSColin Finck 818c2c66affSColin Finck count = CountClipboardFormats(); 819c2c66affSColin Finck ok( count == 1, "%u: count %u\n", i, count ); 820c2c66affSColin Finck 821c2c66affSColin Finck r = CloseClipboard(); 822c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 823c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 824c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered ); 825c2c66affSColin Finck 826c2c66affSColin Finck count = CountClipboardFormats(); 827c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++) 828c2c66affSColin Finck { 829c2c66affSColin Finck r = IsClipboardFormatAvailable( tests[i].expected[j] ); 830c2c66affSColin Finck ok( r, "%u: %04x not available\n", i, tests[i].expected[j] ); 831c2c66affSColin Finck } 832c2c66affSColin Finck ok( count == j, "%u: count %u instead of %u\n", i, count, j ); 833c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 834c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered ); 835c2c66affSColin Finck 836c2c66affSColin Finck r = OpenClipboard(NULL); 837c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 838c2c66affSColin Finck cf = 0; 839c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++) 840c2c66affSColin Finck { 841c2c66affSColin Finck cf = EnumClipboardFormats( cf ); 842c2c66affSColin Finck ok(cf == tests[i].expected[j], "%u.%u: got %04x instead of %04x\n", 843c2c66affSColin Finck i, j, cf, tests[i].expected[j] ); 844c2c66affSColin Finck if (cf != tests[i].expected[j]) break; 845c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 846c2c66affSColin Finck ok( !rendered, "%u.%u: formats %08x have been rendered\n", i, j, rendered ); 847c2c66affSColin Finck data = GetClipboardData( cf ); 848c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 849c2c66affSColin Finck if (cf == CF_LOCALE) 850c2c66affSColin Finck { 851c2c66affSColin Finck ok(data != NULL, "%u: CF_LOCALE no data\n", i); 852c2c66affSColin Finck ok( !rendered, "%u.%u: formats %08x have been rendered\n", i, j, rendered ); 853c2c66affSColin Finck } 854c2c66affSColin Finck else 855c2c66affSColin Finck { 856c2c66affSColin Finck ok(!data, "%u: format %04x got data %p\n", i, cf, data); 857c2c66affSColin Finck ok( rendered == (1 << tests[i].format), 858c2c66affSColin Finck "%u.%u: formats %08x have been rendered\n", i, j, rendered ); 859c2c66affSColin Finck /* try to render a second time */ 860c2c66affSColin Finck data = GetClipboardData( cf ); 861c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 862c2c66affSColin Finck ok( rendered == (1 << tests[i].format), 863c2c66affSColin Finck "%u.%u: formats %08x have been rendered\n", i, j, rendered ); 864c2c66affSColin Finck } 865c2c66affSColin Finck } 866c2c66affSColin Finck if (!tests[i].expected[j]) 867c2c66affSColin Finck { 868c2c66affSColin Finck cf = EnumClipboardFormats( cf ); 869c2c66affSColin Finck ok(cf == 0, "%u: cf %04x\n", i, cf); 870c2c66affSColin Finck } 871c2c66affSColin Finck r = CloseClipboard(); 872c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError()); 873c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 ); 874c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered ); 875c2c66affSColin Finck } 876c2c66affSColin Finck 877c2c66affSColin Finck r = OpenClipboard(NULL); 878c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 879c2c66affSColin Finck r = EmptyClipboard(); 880c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 881c2c66affSColin Finck r = CloseClipboard(); 882c2c66affSColin Finck ok(r, "gle %d\n", GetLastError()); 883c2c66affSColin Finck DestroyWindow( hwnd ); 884c2c66affSColin Finck } 885c2c66affSColin Finck 886c2c66affSColin Finck static DWORD WINAPI clipboard_render_data_thread(void *param) 887c2c66affSColin Finck { 888c2c66affSColin Finck HANDLE handle = SetClipboardData( CF_UNICODETEXT, create_textW() ); 889c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed: %d\n", GetLastError() ); 890c2c66affSColin Finck return 0; 891c2c66affSColin Finck } 892c2c66affSColin Finck 893c2c66affSColin Finck static CRITICAL_SECTION clipboard_cs; 894c2c66affSColin Finck static HWND next_wnd; 895c2c66affSColin Finck static UINT wm_drawclipboard; 896c2c66affSColin Finck static UINT wm_clipboardupdate; 897c2c66affSColin Finck static UINT wm_destroyclipboard; 898c2c66affSColin Finck static UINT wm_renderformat; 899c2c66affSColin Finck static UINT nb_formats; 900c2c66affSColin Finck static BOOL cross_thread; 901c2c66affSColin Finck static BOOL do_render_format; 902*d558fc75SAmine Khaldi static HANDLE update_event; 903c2c66affSColin Finck 904c2c66affSColin Finck static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) 905c2c66affSColin Finck { 906c2c66affSColin Finck LRESULT ret; 907c2c66affSColin Finck DWORD msg_flags = InSendMessageEx( NULL ); 908c2c66affSColin Finck 909c2c66affSColin Finck switch(msg) { 910c2c66affSColin Finck case WM_DRAWCLIPBOARD: 911c2c66affSColin Finck ok( msg_flags == (cross_thread ? ISMEX_NOTIFY : ISMEX_NOSEND), 912c2c66affSColin Finck "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags ); 913c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 914c2c66affSColin Finck wm_drawclipboard++; 915c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 916c2c66affSColin Finck break; 917c2c66affSColin Finck case WM_CHANGECBCHAIN: 918c2c66affSColin Finck ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND), 919c2c66affSColin Finck "WM_CHANGECBCHAIN wrong flags %x\n", msg_flags ); 920c2c66affSColin Finck if (next_wnd == (HWND)wp) 921c2c66affSColin Finck next_wnd = (HWND)lp; 922c2c66affSColin Finck else if (next_wnd) 923c2c66affSColin Finck SendMessageA(next_wnd, msg, wp, lp); 924c2c66affSColin Finck break; 925c2c66affSColin Finck case WM_DESTROYCLIPBOARD: 926c2c66affSColin Finck ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND), 927c2c66affSColin Finck "WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags ); 928c2c66affSColin Finck wm_destroyclipboard++; 929c2c66affSColin Finck ok( GetClipboardOwner() == hwnd, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() ); 930c2c66affSColin Finck nb_formats = CountClipboardFormats(); 931c2c66affSColin Finck break; 932c2c66affSColin Finck case WM_RENDERFORMAT: 933c2c66affSColin Finck ok( !wm_renderformat, "multiple WM_RENDERFORMAT %04x / %04lx\n", wm_renderformat, wp ); 934c2c66affSColin Finck wm_renderformat = wp; 935c2c66affSColin Finck 936c2c66affSColin Finck if (do_render_format) 937c2c66affSColin Finck { 938c2c66affSColin Finck UINT seq, old_seq; 939c2c66affSColin Finck HANDLE handle; 940c2c66affSColin Finck 941c2c66affSColin Finck old_seq = GetClipboardSequenceNumber(); 942c2c66affSColin Finck handle = SetClipboardData( CF_TEXT, create_textA() ); 943c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed: %d\n", GetLastError() ); 944c2c66affSColin Finck seq = GetClipboardSequenceNumber(); 945c2c66affSColin Finck ok( seq == old_seq, "sequence changed\n" ); 946c2c66affSColin Finck old_seq = seq; 947c2c66affSColin Finck 948c2c66affSColin Finck handle = CreateThread( NULL, 0, clipboard_render_data_thread, NULL, 0, NULL ); 949c2c66affSColin Finck ok( handle != NULL, "CreateThread failed: %d\n", GetLastError() ); 950c2c66affSColin Finck ok( WaitForSingleObject(handle, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); 951c2c66affSColin Finck CloseHandle( handle ); 952c2c66affSColin Finck seq = GetClipboardSequenceNumber(); 953c2c66affSColin Finck ok( seq == old_seq, "sequence changed\n" ); 954c2c66affSColin Finck } 955c2c66affSColin Finck 956c2c66affSColin Finck break; 957c2c66affSColin Finck case WM_CLIPBOARDUPDATE: 958c2c66affSColin Finck ok( msg_flags == ISMEX_NOSEND, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags ); 959c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 960c2c66affSColin Finck wm_clipboardupdate++; 961*d558fc75SAmine Khaldi SetEvent(update_event); 962c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 963c2c66affSColin Finck break; 964c2c66affSColin Finck case WM_USER: 965c2c66affSColin Finck ChangeClipboardChain(hwnd, next_wnd); 966c2c66affSColin Finck PostQuitMessage(0); 967c2c66affSColin Finck break; 968c2c66affSColin Finck case WM_USER+1: 969c2c66affSColin Finck ret = wm_drawclipboard; 970c2c66affSColin Finck wm_drawclipboard = 0; 971c2c66affSColin Finck return ret; 972c2c66affSColin Finck case WM_USER+2: 973c2c66affSColin Finck ret = wm_clipboardupdate; 974c2c66affSColin Finck wm_clipboardupdate = 0; 975c2c66affSColin Finck return ret; 976c2c66affSColin Finck case WM_USER+3: 977c2c66affSColin Finck ret = wm_destroyclipboard; 978c2c66affSColin Finck wm_destroyclipboard = 0; 979c2c66affSColin Finck return ret; 980c2c66affSColin Finck case WM_USER+4: 981c2c66affSColin Finck ret = wm_renderformat; 982c2c66affSColin Finck wm_renderformat = 0; 983c2c66affSColin Finck return ret; 984c2c66affSColin Finck case WM_USER+5: 985c2c66affSColin Finck return nb_formats; 986c2c66affSColin Finck } 987c2c66affSColin Finck 988c2c66affSColin Finck return DefWindowProcA(hwnd, msg, wp, lp); 989c2c66affSColin Finck } 990c2c66affSColin Finck 991c2c66affSColin Finck static void get_clipboard_data_process(void) 992c2c66affSColin Finck { 993c2c66affSColin Finck HANDLE data; 994c2c66affSColin Finck BOOL r; 995c2c66affSColin Finck 996c2c66affSColin Finck r = OpenClipboard(0); 997c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 998c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT ); 999c2c66affSColin Finck ok( data != NULL, "GetClipboardData failed: %d\n", GetLastError()); 1000c2c66affSColin Finck r = CloseClipboard(); 1001c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1002c2c66affSColin Finck } 1003c2c66affSColin Finck 1004*d558fc75SAmine Khaldi static UINT old_seq; 1005*d558fc75SAmine Khaldi 1006*d558fc75SAmine Khaldi static void check_messages_(int line, HWND win, UINT seq_diff, UINT draw, UINT update, UINT destroy, UINT render) 1007*d558fc75SAmine Khaldi { 1008*d558fc75SAmine Khaldi MSG msg; 1009*d558fc75SAmine Khaldi UINT count, fmt, seq; 1010*d558fc75SAmine Khaldi 1011*d558fc75SAmine Khaldi seq = GetClipboardSequenceNumber(); 1012*d558fc75SAmine Khaldi ok_(__FILE__, line)(seq - old_seq == seq_diff, "sequence diff %d\n", seq - old_seq); 1013*d558fc75SAmine Khaldi old_seq = seq; 1014*d558fc75SAmine Khaldi 1015*d558fc75SAmine Khaldi if (!cross_thread) 1016*d558fc75SAmine Khaldi { 1017*d558fc75SAmine Khaldi while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); 1018*d558fc75SAmine Khaldi } 1019*d558fc75SAmine Khaldi 1020*d558fc75SAmine Khaldi if (update && !broken(!pAddClipboardFormatListener)) 1021*d558fc75SAmine Khaldi ok(WaitForSingleObject(update_event, 1000) == WAIT_OBJECT_0, "wait failed\n"); 1022*d558fc75SAmine Khaldi 1023*d558fc75SAmine Khaldi count = SendMessageA( win, WM_USER + 1, 0, 0 ); 1024*d558fc75SAmine Khaldi ok_(__FILE__, line)(count == draw, "WM_DRAWCLIPBOARD %sreceived\n", draw ? "not " : ""); 1025*d558fc75SAmine Khaldi count = SendMessageA( win, WM_USER + 2, 0, 0 ); 1026*d558fc75SAmine Khaldi ok_(__FILE__, line)(count == update || broken(!pAddClipboardFormatListener), 1027*d558fc75SAmine Khaldi "WM_CLIPBOARDUPDATE %sreceived\n", update ? "not " : ""); 1028*d558fc75SAmine Khaldi count = SendMessageA( win, WM_USER + 3, 0, 0 ); 1029*d558fc75SAmine Khaldi ok_(__FILE__, line)(count == destroy, "WM_DESTROYCLIPBOARD %sreceived\n", destroy ? "not " : ""); 1030*d558fc75SAmine Khaldi fmt = SendMessageA( win, WM_USER + 4, 0, 0 ); 1031*d558fc75SAmine Khaldi ok_(__FILE__, line)(fmt == render, "WM_RENDERFORMAT received %04x, expected %04x\n", fmt, render); 1032*d558fc75SAmine Khaldi } 1033*d558fc75SAmine Khaldi #define check_messages(a,b,c,d,e,f) check_messages_(__LINE__,a,b,c,d,e,f) 1034*d558fc75SAmine Khaldi 1035c2c66affSColin Finck static DWORD WINAPI clipboard_thread(void *param) 1036c2c66affSColin Finck { 1037c2c66affSColin Finck HWND ret, win = param; 1038c2c66affSColin Finck BOOL r; 1039c2c66affSColin Finck MSG msg; 1040c2c66affSColin Finck HANDLE handle; 1041*d558fc75SAmine Khaldi UINT count, fmt, formats; 1042c2c66affSColin Finck 1043c2c66affSColin Finck cross_thread = (GetWindowThreadProcessId( win, NULL ) != GetCurrentThreadId()); 1044c2c66affSColin Finck trace( "%s-threaded test\n", cross_thread ? "multi" : "single" ); 1045c2c66affSColin Finck 1046c2c66affSColin Finck old_seq = GetClipboardSequenceNumber(); 1047c2c66affSColin Finck 1048c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 1049c2c66affSColin Finck SetLastError(0xdeadbeef); 1050c2c66affSColin Finck next_wnd = SetClipboardViewer(win); 1051c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError()); 1052c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 1053c2c66affSColin Finck 1054c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1055c2c66affSColin Finck ret = SetClipboardViewer( (HWND)0xdead ); 1056c2c66affSColin Finck ok( !ret, "SetClipboardViewer succeeded\n" ); 1057c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() ); 1058c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1059c2c66affSColin Finck r = ChangeClipboardChain( win, (HWND)0xdead ); 1060c2c66affSColin Finck ok( !r, "ChangeClipboardChain succeeded\n" ); 1061c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() ); 1062c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1063c2c66affSColin Finck r = ChangeClipboardChain( (HWND)0xdead, next_wnd ); 1064c2c66affSColin Finck ok( !r, "ChangeClipboardChain succeeded\n" ); 1065c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() ); 1066c2c66affSColin Finck 1067c2c66affSColin Finck if (pAddClipboardFormatListener) 1068c2c66affSColin Finck { 1069c2c66affSColin Finck r = pAddClipboardFormatListener(win); 1070c2c66affSColin Finck ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError()); 1071c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1072c2c66affSColin Finck r = pAddClipboardFormatListener( win ); 1073c2c66affSColin Finck ok( !r, "AddClipboardFormatListener succeeded\n" ); 1074c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 1075c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1076c2c66affSColin Finck r = pAddClipboardFormatListener( (HWND)0xdead ); 1077c2c66affSColin Finck ok( !r, "AddClipboardFormatListener succeeded\n" ); 1078c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() ); 1079c2c66affSColin Finck r = pAddClipboardFormatListener( GetDesktopWindow() ); 1080c2c66affSColin Finck ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError()); 1081c2c66affSColin Finck r = pRemoveClipboardFormatListener( GetDesktopWindow() ); 1082c2c66affSColin Finck ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError()); 1083c2c66affSColin Finck } 1084c2c66affSColin Finck 1085*d558fc75SAmine Khaldi check_messages(win, 0, 1, 0, 0, 0); 1086c2c66affSColin Finck 1087c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1088c2c66affSColin Finck r = OpenClipboard( (HWND)0xdead ); 1089c2c66affSColin Finck ok( !r, "OpenClipboard succeeded\n" ); 1090c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() ); 1091c2c66affSColin Finck 1092c2c66affSColin Finck r = OpenClipboard(win); 1093c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1094c2c66affSColin Finck 1095*d558fc75SAmine Khaldi check_messages(win, 0, 0, 0, 0, 0); 1096c2c66affSColin Finck 1097c2c66affSColin Finck r = EmptyClipboard(); 1098c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError()); 1099c2c66affSColin Finck 1100*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1101c2c66affSColin Finck 1102c2c66affSColin Finck r = EmptyClipboard(); 1103c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError()); 1104c2c66affSColin Finck /* sequence changes again, even though it was already empty */ 1105*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 1, 0); 1106c2c66affSColin Finck count = SendMessageA( win, WM_USER+5, 0, 0 ); 1107c2c66affSColin Finck ok( !count, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count ); 1108c2c66affSColin Finck 1109c2c66affSColin Finck handle = SetClipboardData( CF_TEXT, create_textA() ); 1110c2c66affSColin Finck ok(handle != 0, "SetClipboardData failed: %d\n", GetLastError()); 1111c2c66affSColin Finck 1112*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1113c2c66affSColin Finck 1114c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, 0 ); 1115c2c66affSColin Finck 1116*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1117c2c66affSColin Finck 1118c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, 0 ); /* same data again */ 1119c2c66affSColin Finck 1120*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1121c2c66affSColin Finck 1122c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" ); 1123c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" ); 1124c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_OEMTEXT ), "CF_OEMTEXT available\n" ); 1125c2c66affSColin Finck 1126c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 1127c2c66affSColin Finck r = CloseClipboard(); 1128c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1129c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 1130c2c66affSColin Finck 1131*d558fc75SAmine Khaldi check_messages(win, 2, 1, 1, 0, 0); 1132c2c66affSColin Finck 1133c2c66affSColin Finck r = OpenClipboard(win); 1134c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1135c2c66affSColin Finck 1136*d558fc75SAmine Khaldi check_messages(win, 0, 0, 0, 0, 0); 1137c2c66affSColin Finck 1138c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" ); 1139c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" ); 1140c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_OEMTEXT ), "CF_OEMTEXT available\n" ); 1141c2c66affSColin Finck 1142c2c66affSColin Finck ok( GetClipboardOwner() == win, "wrong owner %p\n", GetClipboardOwner()); 1143c2c66affSColin Finck handle = GetClipboardData( CF_UNICODETEXT ); 1144c2c66affSColin Finck ok( !handle, "got data for CF_UNICODETEXT\n" ); 1145c2c66affSColin Finck fmt = SendMessageA( win, WM_USER+4, 0, 0 ); 1146c2c66affSColin Finck ok( fmt == CF_UNICODETEXT, "WM_RENDERFORMAT received %04x\n", fmt ); 1147c2c66affSColin Finck 1148c2c66affSColin Finck do_render_format = TRUE; 1149c2c66affSColin Finck handle = GetClipboardData( CF_OEMTEXT ); 1150c2c66affSColin Finck ok( handle != NULL, "didn't get data for CF_OEMTEXT\n" ); 1151c2c66affSColin Finck fmt = SendMessageA( win, WM_USER+4, 0, 0 ); 1152c2c66affSColin Finck ok( fmt == CF_UNICODETEXT, "WM_RENDERFORMAT received %04x\n", fmt ); 1153c2c66affSColin Finck do_render_format = FALSE; 1154c2c66affSColin Finck 1155c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 ); 1156*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1157c2c66affSColin Finck 1158c2c66affSColin Finck r = CloseClipboard(); 1159c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1160c2c66affSColin Finck /* no synthesized format, so CloseClipboard doesn't change the sequence */ 1161*d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0); 1162c2c66affSColin Finck 1163c2c66affSColin Finck r = OpenClipboard(win); 1164c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1165c2c66affSColin Finck r = CloseClipboard(); 1166c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1167c2c66affSColin Finck /* nothing changed */ 1168*d558fc75SAmine Khaldi check_messages(win, 0, 0, 0, 0, 0); 1169c2c66affSColin Finck 1170c2c66affSColin Finck formats = CountClipboardFormats(); 1171c2c66affSColin Finck r = OpenClipboard(0); 1172c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1173c2c66affSColin Finck r = EmptyClipboard(); 1174c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError()); 1175c2c66affSColin Finck r = CloseClipboard(); 1176c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1177c2c66affSColin Finck 1178*d558fc75SAmine Khaldi check_messages(win, 1, 1, 1, 1, 0); 1179c2c66affSColin Finck count = SendMessageA( win, WM_USER+5, 0, 0 ); 1180c2c66affSColin Finck ok( count == formats, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count ); 1181c2c66affSColin Finck 1182c2c66affSColin Finck r = OpenClipboard(win); 1183c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1184c2c66affSColin Finck SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 )); 1185*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1186c2c66affSColin Finck 1187c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 1188c2c66affSColin Finck r = CloseClipboard(); 1189c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1190c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 1191c2c66affSColin Finck 1192*d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0); 1193c2c66affSColin Finck 1194c2c66affSColin Finck run_process( "grab_clipboard 0" ); 1195c2c66affSColin Finck 1196c2c66affSColin Finck if (!cross_thread) 1197c2c66affSColin Finck { 1198c2c66affSColin Finck /* in this case we get a cross-thread WM_DRAWCLIPBOARD */ 1199c2c66affSColin Finck cross_thread = TRUE; 1200c2c66affSColin Finck while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); 1201c2c66affSColin Finck cross_thread = FALSE; 1202c2c66affSColin Finck } 1203*d558fc75SAmine Khaldi check_messages(win, 1, 1, 1, 0, 0); 1204c2c66affSColin Finck 1205c2c66affSColin Finck r = OpenClipboard(0); 1206c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1207c2c66affSColin Finck SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 )); 1208*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1209c2c66affSColin Finck 1210c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 1211c2c66affSColin Finck r = CloseClipboard(); 1212c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1213c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 1214c2c66affSColin Finck 1215*d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0); 1216c2c66affSColin Finck 1217c2c66affSColin Finck run_process( "grab_clipboard 1" ); 1218c2c66affSColin Finck 1219c2c66affSColin Finck if (!cross_thread) 1220c2c66affSColin Finck { 1221c2c66affSColin Finck /* in this case we get a cross-thread WM_DRAWCLIPBOARD */ 1222c2c66affSColin Finck cross_thread = TRUE; 1223c2c66affSColin Finck while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); 1224c2c66affSColin Finck cross_thread = FALSE; 1225c2c66affSColin Finck } 1226*d558fc75SAmine Khaldi check_messages(win, 2, 1, 1, 0, 0); 1227c2c66affSColin Finck 1228c2c66affSColin Finck r = OpenClipboard(0); 1229c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1230c2c66affSColin Finck SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 )); 1231*d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0); 1232c2c66affSColin Finck 1233c2c66affSColin Finck EnterCriticalSection(&clipboard_cs); 1234c2c66affSColin Finck r = CloseClipboard(); 1235c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1236c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs); 1237c2c66affSColin Finck 1238*d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0); 1239c2c66affSColin Finck 1240c2c66affSColin Finck if (cross_thread) 1241c2c66affSColin Finck { 1242c2c66affSColin Finck r = OpenClipboard( win ); 1243c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError()); 1244c2c66affSColin Finck r = EmptyClipboard(); 1245c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError()); 1246c2c66affSColin Finck SetClipboardData( CF_TEXT, 0 ); 1247c2c66affSColin Finck r = CloseClipboard(); 1248c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError()); 1249c2c66affSColin Finck 1250c2c66affSColin Finck do_render_format = TRUE; 1251c2c66affSColin Finck old_seq = GetClipboardSequenceNumber(); 1252c2c66affSColin Finck run_process( "get_clipboard_data" ); 1253c2c66affSColin Finck do_render_format = FALSE; 1254c2c66affSColin Finck 1255*d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, CF_TEXT); 1256c2c66affSColin Finck } 1257c2c66affSColin Finck 1258c2c66affSColin Finck r = PostMessageA(win, WM_USER, 0, 0); 1259c2c66affSColin Finck ok(r, "PostMessage failed: %d\n", GetLastError()); 1260c2c66affSColin Finck 1261c2c66affSColin Finck if (pRemoveClipboardFormatListener) 1262c2c66affSColin Finck { 1263c2c66affSColin Finck r = pRemoveClipboardFormatListener(win); 1264c2c66affSColin Finck ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError()); 1265c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1266c2c66affSColin Finck r = pRemoveClipboardFormatListener(win); 1267c2c66affSColin Finck ok( !r, "RemoveClipboardFormatListener succeeded\n" ); 1268c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 1269c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1270c2c66affSColin Finck r = pRemoveClipboardFormatListener( (HWND)0xdead ); 1271c2c66affSColin Finck ok( !r, "RemoveClipboardFormatListener succeeded\n" ); 1272c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() ); 1273c2c66affSColin Finck } 1274c2c66affSColin Finck return 0; 1275c2c66affSColin Finck } 1276c2c66affSColin Finck 1277c2c66affSColin Finck static void test_messages(void) 1278c2c66affSColin Finck { 1279c2c66affSColin Finck WNDCLASSA cls; 1280c2c66affSColin Finck HWND win; 1281c2c66affSColin Finck MSG msg; 1282c2c66affSColin Finck HANDLE thread; 1283c2c66affSColin Finck DWORD tid; 1284c2c66affSColin Finck 1285c2c66affSColin Finck InitializeCriticalSection(&clipboard_cs); 1286*d558fc75SAmine Khaldi update_event = CreateEventW(NULL, FALSE, FALSE, NULL); 1287c2c66affSColin Finck 1288c2c66affSColin Finck memset(&cls, 0, sizeof(cls)); 1289c2c66affSColin Finck cls.lpfnWndProc = clipboard_wnd_proc; 1290c2c66affSColin Finck cls.hInstance = GetModuleHandleA(NULL); 1291c2c66affSColin Finck cls.lpszClassName = "clipboard_test"; 1292c2c66affSColin Finck RegisterClassA(&cls); 1293c2c66affSColin Finck 1294c2c66affSColin Finck win = CreateWindowA("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0); 1295c2c66affSColin Finck ok(win != NULL, "CreateWindow failed: %d\n", GetLastError()); 1296c2c66affSColin Finck 1297c2c66affSColin Finck thread = CreateThread(NULL, 0, clipboard_thread, (void*)win, 0, &tid); 1298c2c66affSColin Finck ok(thread != NULL, "CreateThread failed: %d\n", GetLastError()); 1299c2c66affSColin Finck 1300c2c66affSColin Finck while(GetMessageA(&msg, NULL, 0, 0)) 1301c2c66affSColin Finck { 1302c2c66affSColin Finck ok( msg.message != WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD was posted\n" ); 1303c2c66affSColin Finck TranslateMessage(&msg); 1304c2c66affSColin Finck DispatchMessageA(&msg); 1305c2c66affSColin Finck } 1306c2c66affSColin Finck 1307c2c66affSColin Finck ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); 1308c2c66affSColin Finck CloseHandle(thread); 1309c2c66affSColin Finck 1310c2c66affSColin Finck DestroyWindow( win ); 1311c2c66affSColin Finck 1312c2c66affSColin Finck /* same tests again but inside a single thread */ 1313c2c66affSColin Finck 1314c2c66affSColin Finck win = CreateWindowA( "clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0 ); 1315c2c66affSColin Finck ok( win != NULL, "CreateWindow failed: %d\n", GetLastError() ); 1316c2c66affSColin Finck 1317c2c66affSColin Finck clipboard_thread( win ); 1318c2c66affSColin Finck DestroyWindow( win ); 1319c2c66affSColin Finck 1320c2c66affSColin Finck UnregisterClassA("clipboard_test", GetModuleHandleA(NULL)); 1321c2c66affSColin Finck DeleteCriticalSection(&clipboard_cs); 1322c2c66affSColin Finck } 1323c2c66affSColin Finck 1324c2c66affSColin Finck static BOOL is_moveable( HANDLE handle ) 1325c2c66affSColin Finck { 1326c2c66affSColin Finck void *ptr = GlobalLock( handle ); 1327c2c66affSColin Finck if (ptr) GlobalUnlock( handle ); 1328c2c66affSColin Finck return ptr && ptr != handle; 1329c2c66affSColin Finck } 1330c2c66affSColin Finck 1331c2c66affSColin Finck static BOOL is_fixed( HANDLE handle ) 1332c2c66affSColin Finck { 1333c2c66affSColin Finck void *ptr = GlobalLock( handle ); 1334c2c66affSColin Finck if (ptr) GlobalUnlock( handle ); 1335c2c66affSColin Finck return ptr && ptr == handle; 1336c2c66affSColin Finck } 1337c2c66affSColin Finck 1338c2c66affSColin Finck static BOOL is_freed( HANDLE handle ) 1339c2c66affSColin Finck { 1340c2c66affSColin Finck return !GlobalSize( handle ); 1341c2c66affSColin Finck } 1342c2c66affSColin Finck 1343c2c66affSColin Finck static UINT format_id; 1344c2c66affSColin Finck static HBITMAP bitmap, bitmap2; 1345c2c66affSColin Finck static HPALETTE palette; 1346c2c66affSColin Finck static const LOGPALETTE logpalette = { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}}; 1347c2c66affSColin Finck 1348c2c66affSColin Finck static void test_handles( HWND hwnd ) 1349c2c66affSColin Finck { 1350c2c66affSColin Finck HGLOBAL h, htext, htext2, htext3, htext4, htext5; 1351c2c66affSColin Finck HGLOBAL hfixed, hfixed2, hmoveable, empty_fixed, empty_moveable; 1352c2c66affSColin Finck void *ptr; 1353c2c66affSColin Finck UINT format_id2 = RegisterClipboardFormatA( "another format" ); 1354c2c66affSColin Finck BOOL r; 1355c2c66affSColin Finck HANDLE data; 1356c2c66affSColin Finck HBITMAP bitmap_temp; 1357c2c66affSColin Finck DWORD process; 1358c2c66affSColin Finck BOOL is_owner = (GetWindowThreadProcessId( hwnd, &process ) && process == GetCurrentProcessId()); 1359c2c66affSColin Finck 1360c2c66affSColin Finck trace( "hwnd %p\n", hwnd ); 1361c2c66affSColin Finck htext = create_textA(); 1362c2c66affSColin Finck htext2 = create_textA(); 1363c2c66affSColin Finck htext3 = create_textA(); 1364c2c66affSColin Finck htext4 = create_textA(); 1365c2c66affSColin Finck htext5 = create_textA(); 1366c2c66affSColin Finck bitmap = CreateBitmap( 10, 10, 1, 1, NULL ); 1367c2c66affSColin Finck bitmap2 = CreateBitmap( 10, 10, 1, 1, NULL ); 1368c2c66affSColin Finck palette = CreatePalette( &logpalette ); 1369c2c66affSColin Finck 1370c2c66affSColin Finck hfixed = GlobalAlloc( GMEM_FIXED, 17 ); 1371c2c66affSColin Finck hfixed2 = GlobalAlloc( GMEM_FIXED, 17 ); 1372c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed ); 1373c2c66affSColin Finck ok( GlobalSize( hfixed ) == 17, "wrong size %lu\n", GlobalSize( hfixed )); 1374c2c66affSColin Finck 1375c2c66affSColin Finck hmoveable = GlobalAlloc( GMEM_MOVEABLE, 23 ); 1376c2c66affSColin Finck ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable ); 1377c2c66affSColin Finck ok( GlobalSize( hmoveable ) == 23, "wrong size %lu\n", GlobalSize( hmoveable )); 1378c2c66affSColin Finck 1379c2c66affSColin Finck empty_fixed = GlobalAlloc( GMEM_FIXED, 0 ); 1380c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed ); 1381c2c66affSColin Finck 1382c2c66affSColin Finck empty_moveable = GlobalAlloc( GMEM_MOVEABLE, 0 ); 1383c2c66affSColin Finck /* discarded handles can't be GlobalLock'ed */ 1384c2c66affSColin Finck ok( is_freed( empty_moveable ), "expected free mem %p\n", empty_moveable ); 1385c2c66affSColin Finck 1386c2c66affSColin Finck r = OpenClipboard( hwnd ); 1387c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1388c2c66affSColin Finck r = EmptyClipboard(); 1389c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1390c2c66affSColin Finck 1391c2c66affSColin Finck h = SetClipboardData( CF_TEXT, htext ); 1392c2c66affSColin Finck ok( h == htext, "got %p\n", h ); 1393c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1394c2c66affSColin Finck h = SetClipboardData( format_id, htext2 ); 1395c2c66affSColin Finck ok( h == htext2, "got %p\n", h ); 1396c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1397c2c66affSColin Finck bitmap_temp = CreateBitmap( 10, 10, 1, 1, NULL ); 1398c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap_temp ); 1399c2c66affSColin Finck ok( h == bitmap_temp, "got %p\n", h ); 1400c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1401c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap ); 1402c2c66affSColin Finck ok( h == bitmap, "got %p\n", h ); 1403c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1404c2c66affSColin Finck ok( !GetObjectType( bitmap_temp ), "expected free object %p\n", bitmap_temp ); 1405c2c66affSColin Finck h = SetClipboardData( CF_DSPBITMAP, bitmap2 ); 1406c2c66affSColin Finck ok( h == bitmap2, "got %p\n", h ); 1407c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1408c2c66affSColin Finck h = SetClipboardData( CF_PALETTE, palette ); 1409c2c66affSColin Finck ok( h == palette, "got %p\n", h ); 1410c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h ); 1411c2c66affSColin Finck h = SetClipboardData( CF_GDIOBJFIRST + 3, htext3 ); 1412c2c66affSColin Finck ok( h == htext3, "got %p\n", h ); 1413c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1414c2c66affSColin Finck h = SetClipboardData( CF_PRIVATEFIRST + 7, htext5 ); 1415c2c66affSColin Finck ok( h == htext5, "got %p\n", h ); 1416c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1417c2c66affSColin Finck h = SetClipboardData( format_id2, empty_moveable ); 1418c2c66affSColin Finck ok( !h, "got %p\n", h ); 1419c2c66affSColin Finck GlobalFree( empty_moveable ); 1420c2c66affSColin Finck 1421c2c66affSColin Finck if (0) /* crashes on vista64 */ 1422c2c66affSColin Finck { 1423c2c66affSColin Finck ptr = HeapAlloc( GetProcessHeap(), 0, 0 ); 1424c2c66affSColin Finck h = SetClipboardData( format_id2, ptr ); 1425c2c66affSColin Finck ok( !h, "got %p\n", h ); 1426c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, ptr ); 1427c2c66affSColin Finck } 1428c2c66affSColin Finck 1429c2c66affSColin Finck h = SetClipboardData( format_id2, empty_fixed ); 1430c2c66affSColin Finck ok( h == empty_fixed, "got %p\n", h ); 1431c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1432c2c66affSColin Finck h = SetClipboardData( 0xdeadbeef, hfixed2 ); 1433c2c66affSColin Finck ok( h == hfixed2, "got %p\n", h ); 1434c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1435c2c66affSColin Finck h = SetClipboardData( 0xdeadbabe, hmoveable ); 1436c2c66affSColin Finck ok( h == hmoveable, "got %p\n", h ); 1437c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1438c2c66affSColin Finck 1439c2c66affSColin Finck ptr = HeapAlloc( GetProcessHeap(), 0, 37 ); 1440c2c66affSColin Finck h = SetClipboardData( 0xdeadfade, ptr ); 1441c2c66affSColin Finck ok( h == ptr || !h, "got %p\n", h ); 1442c2c66affSColin Finck if (!h) /* heap blocks are rejected on >= win8 */ 1443c2c66affSColin Finck { 1444c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, ptr ); 1445c2c66affSColin Finck ptr = NULL; 1446c2c66affSColin Finck } 1447c2c66affSColin Finck 1448c2c66affSColin Finck data = GetClipboardData( CF_TEXT ); 1449c2c66affSColin Finck ok( data == htext, "wrong data %p\n", data ); 1450c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data ); 1451c2c66affSColin Finck 1452c2c66affSColin Finck data = GetClipboardData( format_id ); 1453c2c66affSColin Finck ok( data == htext2, "wrong data %p, cf %08x\n", data, format_id ); 1454c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data ); 1455c2c66affSColin Finck 1456c2c66affSColin Finck data = GetClipboardData( CF_GDIOBJFIRST + 3 ); 1457c2c66affSColin Finck ok( data == htext3, "wrong data %p\n", data ); 1458c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data ); 1459c2c66affSColin Finck 1460c2c66affSColin Finck data = GetClipboardData( CF_PRIVATEFIRST + 7 ); 1461c2c66affSColin Finck ok( data == htext5, "wrong data %p\n", data ); 1462c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data ); 1463c2c66affSColin Finck 1464c2c66affSColin Finck data = GetClipboardData( format_id2 ); 1465c2c66affSColin Finck ok( data == empty_fixed, "wrong data %p\n", data ); 1466c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1467c2c66affSColin Finck 1468c2c66affSColin Finck data = GetClipboardData( 0xdeadbeef ); 1469c2c66affSColin Finck ok( data == hfixed2, "wrong data %p\n", data ); 1470c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1471c2c66affSColin Finck 1472c2c66affSColin Finck data = GetClipboardData( 0xdeadbabe ); 1473c2c66affSColin Finck ok( data == hmoveable, "wrong data %p\n", data ); 1474c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data ); 1475c2c66affSColin Finck 1476c2c66affSColin Finck data = GetClipboardData( 0xdeadfade ); 1477c2c66affSColin Finck ok( data == ptr, "wrong data %p\n", data ); 1478c2c66affSColin Finck 1479c2c66affSColin Finck h = SetClipboardData( CF_PRIVATEFIRST + 7, htext4 ); 1480c2c66affSColin Finck ok( h == htext4, "got %p\n", h ); 1481c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1482c2c66affSColin Finck ok( is_freed( htext5 ), "expected freed mem %p\n", htext5 ); 1483c2c66affSColin Finck 1484c2c66affSColin Finck h = SetClipboardData( 0xdeadbeef, hfixed ); 1485c2c66affSColin Finck ok( h == hfixed, "got %p\n", h ); 1486c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1487*d558fc75SAmine Khaldi if (0) /* this test is unreliable / crashes */ 1488*d558fc75SAmine Khaldi ok( is_freed( hfixed2 ), "expected freed mem %p\n", hfixed2 ); 1489c2c66affSColin Finck 1490c2c66affSColin Finck r = CloseClipboard(); 1491c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1492c2c66affSColin Finck 1493c2c66affSColin Finck /* data handles are still valid */ 1494c2c66affSColin Finck ok( is_moveable( htext ), "expected moveable mem %p\n", htext ); 1495c2c66affSColin Finck ok( is_moveable( htext2 ), "expected moveable mem %p\n", htext2 ); 1496c2c66affSColin Finck ok( is_moveable( htext3 ), "expected moveable mem %p\n", htext3 ); 1497c2c66affSColin Finck ok( is_moveable( htext4 ), "expected moveable mem %p\n", htext4 ); 1498c2c66affSColin Finck ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap ); 1499c2c66affSColin Finck ok( GetObjectType( bitmap2 ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap2 ); 1500c2c66affSColin Finck ok( GetObjectType( palette ) == OBJ_PAL, "expected palette %p\n", palette ); 1501c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed ); 1502c2c66affSColin Finck ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable ); 1503c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed ); 1504c2c66affSColin Finck 1505c2c66affSColin Finck r = OpenClipboard( hwnd ); 1506c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1507c2c66affSColin Finck 1508c2c66affSColin Finck /* and now they are freed, unless we are the owner */ 1509c2c66affSColin Finck if (!is_owner) 1510c2c66affSColin Finck { 1511c2c66affSColin Finck ok( is_freed( htext ), "expected freed mem %p\n", htext ); 1512c2c66affSColin Finck ok( is_freed( htext2 ), "expected freed mem %p\n", htext2 ); 1513c2c66affSColin Finck ok( is_freed( htext3 ), "expected freed mem %p\n", htext3 ); 1514c2c66affSColin Finck ok( is_freed( htext4 ), "expected freed mem %p\n", htext4 ); 1515c2c66affSColin Finck ok( is_freed( hmoveable ), "expected freed mem %p\n", hmoveable ); 1516c2c66affSColin Finck 1517c2c66affSColin Finck data = GetClipboardData( CF_TEXT ); 1518c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1519c2c66affSColin Finck 1520c2c66affSColin Finck data = GetClipboardData( format_id ); 1521c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1522c2c66affSColin Finck 1523c2c66affSColin Finck data = GetClipboardData( CF_GDIOBJFIRST + 3 ); 1524c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1525c2c66affSColin Finck 1526c2c66affSColin Finck data = GetClipboardData( CF_PRIVATEFIRST + 7 ); 1527c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1528c2c66affSColin Finck 1529c2c66affSColin Finck data = GetClipboardData( format_id2 ); 1530c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1531c2c66affSColin Finck ok( GlobalSize( data ) == 1, "wrong size %lu\n", GlobalSize( data )); 1532c2c66affSColin Finck 1533c2c66affSColin Finck data = GetClipboardData( 0xdeadbeef ); 1534c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1535c2c66affSColin Finck ok( GlobalSize( data ) == 17, "wrong size %lu\n", GlobalSize( data )); 1536c2c66affSColin Finck 1537c2c66affSColin Finck data = GetClipboardData( 0xdeadbabe ); 1538c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1539c2c66affSColin Finck ok( GlobalSize( data ) == 23, "wrong size %lu\n", GlobalSize( data )); 1540c2c66affSColin Finck 1541c2c66affSColin Finck data = GetClipboardData( 0xdeadfade ); 1542c2c66affSColin Finck ok( is_fixed( data ) || !ptr, "expected fixed mem %p\n", data ); 1543c2c66affSColin Finck if (ptr) ok( GlobalSize( data ) == 37, "wrong size %lu\n", GlobalSize( data )); 1544c2c66affSColin Finck } 1545c2c66affSColin Finck else 1546c2c66affSColin Finck { 1547c2c66affSColin Finck ok( is_moveable( htext ), "expected moveable mem %p\n", htext ); 1548c2c66affSColin Finck ok( is_moveable( htext2 ), "expected moveable mem %p\n", htext2 ); 1549c2c66affSColin Finck ok( is_moveable( htext3 ), "expected moveable mem %p\n", htext3 ); 1550c2c66affSColin Finck ok( is_moveable( htext4 ), "expected moveable mem %p\n", htext4 ); 1551c2c66affSColin Finck ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable ); 1552c2c66affSColin Finck 1553c2c66affSColin Finck data = GetClipboardData( CF_TEXT ); 1554c2c66affSColin Finck ok( data == htext, "wrong data %p\n", data ); 1555c2c66affSColin Finck 1556c2c66affSColin Finck data = GetClipboardData( format_id ); 1557c2c66affSColin Finck ok( data == htext2, "wrong data %p, cf %08x\n", data, format_id ); 1558c2c66affSColin Finck 1559c2c66affSColin Finck data = GetClipboardData( CF_GDIOBJFIRST + 3 ); 1560c2c66affSColin Finck ok( data == htext3, "wrong data %p\n", data ); 1561c2c66affSColin Finck 1562c2c66affSColin Finck data = GetClipboardData( CF_PRIVATEFIRST + 7 ); 1563c2c66affSColin Finck ok( data == htext4, "wrong data %p\n", data ); 1564c2c66affSColin Finck 1565c2c66affSColin Finck data = GetClipboardData( format_id2 ); 1566c2c66affSColin Finck ok( data == empty_fixed, "wrong data %p\n", data ); 1567c2c66affSColin Finck 1568c2c66affSColin Finck data = GetClipboardData( 0xdeadbeef ); 1569c2c66affSColin Finck ok( data == hfixed, "wrong data %p\n", data ); 1570c2c66affSColin Finck 1571c2c66affSColin Finck data = GetClipboardData( 0xdeadbabe ); 1572c2c66affSColin Finck ok( data == hmoveable, "wrong data %p\n", data ); 1573c2c66affSColin Finck 1574c2c66affSColin Finck data = GetClipboardData( 0xdeadfade ); 1575c2c66affSColin Finck ok( data == ptr, "wrong data %p\n", data ); 1576c2c66affSColin Finck } 1577c2c66affSColin Finck 1578c2c66affSColin Finck data = GetClipboardData( CF_OEMTEXT ); 1579c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1580c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT ); 1581c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1582c2c66affSColin Finck data = GetClipboardData( CF_LOCALE ); 1583c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1584c2c66affSColin Finck data = GetClipboardData( CF_BITMAP ); 1585c2c66affSColin Finck ok( data == bitmap, "expected bitmap %p\n", data ); 1586c2c66affSColin Finck data = GetClipboardData( CF_DSPBITMAP ); 1587c2c66affSColin Finck ok( data == bitmap2, "expected bitmap %p\n", data ); 1588c2c66affSColin Finck data = GetClipboardData( CF_PALETTE ); 1589c2c66affSColin Finck ok( data == palette, "expected palette %p\n", data ); 1590c2c66affSColin Finck data = GetClipboardData( CF_DIB ); 1591c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1592c2c66affSColin Finck data = GetClipboardData( CF_DIBV5 ); 1593c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data ); 1594c2c66affSColin Finck 1595c2c66affSColin Finck ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap ); 1596c2c66affSColin Finck ok( GetObjectType( bitmap2 ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap2 ); 1597c2c66affSColin Finck ok( GetObjectType( palette ) == OBJ_PAL, "expected palette %p\n", palette ); 1598c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed ); 1599c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed ); 1600c2c66affSColin Finck 1601c2c66affSColin Finck r = EmptyClipboard(); 1602c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1603c2c66affSColin Finck 1604c2c66affSColin Finck /* w2003, w2008 don't seem to free the data here */ 1605c2c66affSColin Finck ok( is_freed( htext ) || broken( !is_freed( htext )), "expected freed mem %p\n", htext ); 1606c2c66affSColin Finck ok( is_freed( htext2 ) || broken( !is_freed( htext2 )), "expected freed mem %p\n", htext2 ); 1607c2c66affSColin Finck ok( is_freed( htext3 ) || broken( !is_freed( htext3 )), "expected freed mem %p\n", htext3 ); 1608c2c66affSColin Finck ok( is_freed( htext4 ) || broken( !is_freed( htext4 )), "expected freed mem %p\n", htext4 ); 1609c2c66affSColin Finck ok( is_freed( hmoveable ) || broken( !is_freed( hmoveable )), "expected freed mem %p\n", hmoveable ); 1610c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed ); 1611c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed ); 1612c2c66affSColin Finck ok( !GetObjectType( bitmap ), "expected freed handle %p\n", bitmap ); 1613c2c66affSColin Finck ok( !GetObjectType( bitmap2 ), "expected freed handle %p\n", bitmap2 ); 1614c2c66affSColin Finck ok( !GetObjectType( palette ), "expected freed handle %p\n", palette ); 1615c2c66affSColin Finck 1616c2c66affSColin Finck r = CloseClipboard(); 1617c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1618c2c66affSColin Finck } 1619c2c66affSColin Finck 1620c2c66affSColin Finck static DWORD WINAPI test_handles_thread( void *arg ) 1621c2c66affSColin Finck { 1622c2c66affSColin Finck trace( "running from different thread\n" ); 1623c2c66affSColin Finck test_handles( (HWND)arg ); 1624c2c66affSColin Finck return 0; 1625c2c66affSColin Finck } 1626c2c66affSColin Finck 1627c2c66affSColin Finck static DWORD WINAPI test_handles_thread2( void *arg ) 1628c2c66affSColin Finck { 1629c2c66affSColin Finck BOOL r; 1630c2c66affSColin Finck HANDLE h; 1631c2c66affSColin Finck char *ptr; 1632c2c66affSColin Finck 1633c2c66affSColin Finck r = OpenClipboard( 0 ); 1634c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1635c2c66affSColin Finck h = GetClipboardData( CF_TEXT ); 1636c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1637c2c66affSColin Finck ptr = GlobalLock( h ); 1638c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr ); 1639c2c66affSColin Finck GlobalUnlock( h ); 1640c2c66affSColin Finck h = GetClipboardData( format_id ); 1641c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1642c2c66affSColin Finck ptr = GlobalLock( h ); 1643c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr ); 1644c2c66affSColin Finck GlobalUnlock( h ); 1645c2c66affSColin Finck h = GetClipboardData( CF_GDIOBJFIRST + 3 ); 1646c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1647c2c66affSColin Finck ptr = GlobalLock( h ); 1648c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr ); 1649c2c66affSColin Finck GlobalUnlock( h ); 1650c2c66affSColin Finck trace( "gdiobj %p\n", h ); 1651c2c66affSColin Finck h = GetClipboardData( CF_PRIVATEFIRST + 7 ); 1652c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1653c2c66affSColin Finck ptr = GlobalLock( h ); 1654c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr ); 1655c2c66affSColin Finck GlobalUnlock( h ); 1656c2c66affSColin Finck trace( "private %p\n", h ); 1657c2c66affSColin Finck h = GetClipboardData( CF_BITMAP ); 1658c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1659c2c66affSColin Finck ok( h == bitmap, "different bitmap %p / %p\n", h, bitmap ); 1660c2c66affSColin Finck trace( "bitmap %p\n", h ); 1661c2c66affSColin Finck h = GetClipboardData( CF_DSPBITMAP ); 1662c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1663c2c66affSColin Finck ok( h == bitmap2, "different bitmap %p / %p\n", h, bitmap2 ); 1664c2c66affSColin Finck trace( "bitmap2 %p\n", h ); 1665c2c66affSColin Finck h = GetClipboardData( CF_PALETTE ); 1666c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h ); 1667c2c66affSColin Finck ok( h == palette, "different palette %p / %p\n", h, palette ); 1668c2c66affSColin Finck trace( "palette %p\n", h ); 1669c2c66affSColin Finck h = GetClipboardData( CF_DIB ); 1670c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1671c2c66affSColin Finck h = GetClipboardData( CF_DIBV5 ); 1672c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1673c2c66affSColin Finck r = CloseClipboard(); 1674c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1675c2c66affSColin Finck return 0; 1676c2c66affSColin Finck } 1677c2c66affSColin Finck 1678c2c66affSColin Finck static void test_handles_process( const char *str ) 1679c2c66affSColin Finck { 1680c2c66affSColin Finck BOOL r; 1681c2c66affSColin Finck HANDLE h; 1682c2c66affSColin Finck char *ptr; 1683c2c66affSColin Finck BITMAP bm; 1684c2c66affSColin Finck PALETTEENTRY entry; 1685c2c66affSColin Finck BYTE buffer[1024]; 1686c2c66affSColin Finck 1687c2c66affSColin Finck format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" ); 1688c2c66affSColin Finck r = OpenClipboard( 0 ); 1689c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1690c2c66affSColin Finck h = GetClipboardData( CF_TEXT ); 1691c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1692c2c66affSColin Finck ptr = GlobalLock( h ); 1693c2c66affSColin Finck ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr ); 1694c2c66affSColin Finck GlobalUnlock( h ); 1695c2c66affSColin Finck h = GetClipboardData( format_id ); 1696c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1697c2c66affSColin Finck ptr = GlobalLock( h ); 1698c2c66affSColin Finck if (ptr) ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr ); 1699c2c66affSColin Finck GlobalUnlock( h ); 1700c2c66affSColin Finck h = GetClipboardData( CF_GDIOBJFIRST + 3 ); 1701c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1702c2c66affSColin Finck ptr = GlobalLock( h ); 1703c2c66affSColin Finck ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr ); 1704c2c66affSColin Finck GlobalUnlock( h ); 1705c2c66affSColin Finck trace( "gdiobj %p\n", h ); 1706c2c66affSColin Finck h = GetClipboardData( CF_PRIVATEFIRST + 7 ); 1707c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1708c2c66affSColin Finck ptr = GlobalLock( h ); 1709c2c66affSColin Finck ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr ); 1710c2c66affSColin Finck GlobalUnlock( h ); 1711c2c66affSColin Finck trace( "private %p\n", h ); 1712c2c66affSColin Finck h = GetClipboardData( CF_BITMAP ); 1713c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1714c2c66affSColin Finck ok( GetObjectW( h, sizeof(bm), &bm ) == sizeof(bm), "GetObject %p failed\n", h ); 1715c2c66affSColin Finck ok( bm.bmWidth == 13 && bm.bmHeight == 17, "wrong bitmap %ux%u\n", bm.bmWidth, bm.bmHeight ); 1716c2c66affSColin Finck trace( "bitmap %p\n", h ); 1717c2c66affSColin Finck h = GetClipboardData( CF_DSPBITMAP ); 1718c2c66affSColin Finck ok( !GetObjectType( h ), "expected invalid object %p\n", h ); 1719c2c66affSColin Finck trace( "bitmap2 %p\n", h ); 1720c2c66affSColin Finck h = GetClipboardData( CF_PALETTE ); 1721c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h ); 1722c2c66affSColin Finck ok( GetPaletteEntries( h, 0, 1, &entry ) == 1, "GetPaletteEntries %p failed\n", h ); 1723c2c66affSColin Finck ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56, 1724c2c66affSColin Finck "wrong color %02x,%02x,%02x\n", entry.peRed, entry.peGreen, entry.peBlue ); 1725c2c66affSColin Finck trace( "palette %p\n", h ); 1726c2c66affSColin Finck h = GetClipboardData( CF_METAFILEPICT ); 1727c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1728c2c66affSColin Finck #ifdef __REACTOS__ 1729c2c66affSColin Finck if (h != NULL) 1730c2c66affSColin Finck #endif 1731c2c66affSColin Finck ok( GetObjectType( ((METAFILEPICT *)h)->hMF ) == OBJ_METAFILE, 1732c2c66affSColin Finck "wrong object %p\n", ((METAFILEPICT *)h)->hMF ); 1733c2c66affSColin Finck trace( "metafile %p\n", h ); 1734c2c66affSColin Finck h = GetClipboardData( CF_DSPMETAFILEPICT ); 1735c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1736c2c66affSColin Finck #ifdef __REACTOS__ 1737c2c66affSColin Finck if (h != NULL) 1738c2c66affSColin Finck #endif 1739c2c66affSColin Finck ok( GetObjectType( ((METAFILEPICT *)h)->hMF ) == OBJ_METAFILE, 1740c2c66affSColin Finck "wrong object %p\n", ((METAFILEPICT *)h)->hMF ); 1741c2c66affSColin Finck trace( "metafile2 %p\n", h ); 1742c2c66affSColin Finck h = GetClipboardData( CF_ENHMETAFILE ); 1743c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h ); 1744c2c66affSColin Finck ok( GetEnhMetaFileBits( h, sizeof(buffer), buffer ) > sizeof(ENHMETAHEADER), 1745c2c66affSColin Finck "GetEnhMetaFileBits failed on %p\n", h ); 1746c2c66affSColin Finck ok( ((ENHMETAHEADER *)buffer)->nRecords == 3, 1747c2c66affSColin Finck "wrong records %u\n", ((ENHMETAHEADER *)buffer)->nRecords ); 1748c2c66affSColin Finck trace( "enhmetafile %p\n", h ); 1749c2c66affSColin Finck h = GetClipboardData( CF_DSPENHMETAFILE ); 1750c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h ); 1751c2c66affSColin Finck ok( GetEnhMetaFileBits( h, sizeof(buffer), buffer ) > sizeof(ENHMETAHEADER), 1752c2c66affSColin Finck "GetEnhMetaFileBits failed on %p\n", h ); 1753c2c66affSColin Finck ok( ((ENHMETAHEADER *)buffer)->nRecords == 3, 1754c2c66affSColin Finck "wrong records %u\n", ((ENHMETAHEADER *)buffer)->nRecords ); 1755c2c66affSColin Finck trace( "enhmetafile2 %p\n", h ); 1756c2c66affSColin Finck h = GetClipboardData( CF_DIB ); 1757c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1758c2c66affSColin Finck h = GetClipboardData( CF_DIBV5 ); 1759c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1760c2c66affSColin Finck r = CloseClipboard(); 1761c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1762c2c66affSColin Finck } 1763c2c66affSColin Finck 1764c2c66affSColin Finck static void test_handles_process_open( const char *str ) 1765c2c66affSColin Finck { 1766c2c66affSColin Finck HANDLE h, text = GlobalAlloc( GMEM_DDESHARE|GMEM_MOVEABLE, strlen(str) + 1 ); 1767c2c66affSColin Finck char *ptr = GlobalLock( text ); 1768c2c66affSColin Finck 1769c2c66affSColin Finck strcpy( ptr, str ); 1770c2c66affSColin Finck GlobalUnlock( text ); 1771c2c66affSColin Finck 1772c2c66affSColin Finck /* clipboard already open by parent process */ 1773c2c66affSColin Finck h = SetClipboardData( CF_TEXT, text ); 1774c2c66affSColin Finck ok( h == text, "wrong mem %p / %p\n", h, text ); 1775c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1776c2c66affSColin Finck } 1777c2c66affSColin Finck 1778c2c66affSColin Finck static void test_handles_process_dib( const char *str ) 1779c2c66affSColin Finck { 1780c2c66affSColin Finck BOOL r; 1781c2c66affSColin Finck HANDLE h; 1782c2c66affSColin Finck 1783c2c66affSColin Finck r = OpenClipboard( 0 ); 1784c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1785c2c66affSColin Finck h = GetClipboardData( CF_BITMAP ); 1786c2c66affSColin Finck ok( !GetObjectType( h ), "expected invalid object %p\n", h ); 1787c2c66affSColin Finck trace( "dibsection %p\n", h ); 1788c2c66affSColin Finck r = CloseClipboard(); 1789c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1790c2c66affSColin Finck } 1791c2c66affSColin Finck 1792c2c66affSColin Finck static void test_data_handles(void) 1793c2c66affSColin Finck { 1794c2c66affSColin Finck BOOL r; 1795c2c66affSColin Finck char *ptr; 1796c2c66affSColin Finck HANDLE h, text; 1797c2c66affSColin Finck HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL ); 1798c2c66affSColin Finck BITMAPINFO bmi; 1799c2c66affSColin Finck void *bits; 1800c2c66affSColin Finck 1801c2c66affSColin Finck ok( hwnd != 0, "window creation failed\n" ); 1802c2c66affSColin Finck format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" ); 1803c2c66affSColin Finck test_handles( 0 ); 1804c2c66affSColin Finck test_handles( GetDesktopWindow() ); 1805c2c66affSColin Finck test_handles( hwnd ); 1806c2c66affSColin Finck run_thread( test_handles_thread, hwnd, __LINE__ ); 1807c2c66affSColin Finck 1808c2c66affSColin Finck bitmap = CreateBitmap( 13, 17, 1, 1, NULL ); 1809c2c66affSColin Finck bitmap2 = CreateBitmap( 10, 10, 1, 1, NULL ); 1810c2c66affSColin Finck palette = CreatePalette( &logpalette ); 1811c2c66affSColin Finck 1812c2c66affSColin Finck r = OpenClipboard( hwnd ); 1813c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1814c2c66affSColin Finck r = EmptyClipboard(); 1815c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1816c2c66affSColin Finck h = SetClipboardData( CF_TEXT, create_textA() ); 1817c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1818c2c66affSColin Finck h = SetClipboardData( format_id, create_textA() ); 1819c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1820c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap ); 1821c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1822c2c66affSColin Finck h = SetClipboardData( CF_DSPBITMAP, bitmap2 ); 1823c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1824c2c66affSColin Finck h = SetClipboardData( CF_PALETTE, palette ); 1825c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h ); 1826c2c66affSColin Finck h = SetClipboardData( CF_METAFILEPICT, create_metafile() ); 1827c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1828c2c66affSColin Finck trace( "metafile %p\n", h ); 1829c2c66affSColin Finck h = SetClipboardData( CF_DSPMETAFILEPICT, create_metafile() ); 1830c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1831c2c66affSColin Finck trace( "metafile2 %p\n", h ); 1832c2c66affSColin Finck h = SetClipboardData( CF_ENHMETAFILE, create_emf() ); 1833c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h ); 1834c2c66affSColin Finck trace( "enhmetafile %p\n", h ); 1835c2c66affSColin Finck h = SetClipboardData( CF_DSPENHMETAFILE, create_emf() ); 1836c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h ); 1837c2c66affSColin Finck trace( "enhmetafile2 %p\n", h ); 1838c2c66affSColin Finck h = SetClipboardData( CF_GDIOBJFIRST + 3, create_textA() ); 1839c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1840c2c66affSColin Finck h = SetClipboardData( CF_PRIVATEFIRST + 7, create_textA() ); 1841c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1842c2c66affSColin Finck r = CloseClipboard(); 1843c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1844c2c66affSColin Finck 1845c2c66affSColin Finck run_thread( test_handles_thread2, 0, __LINE__ ); 1846c2c66affSColin Finck run_process( "handles test" ); 1847c2c66affSColin Finck 1848c2c66affSColin Finck r = OpenClipboard( hwnd ); 1849c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1850c2c66affSColin Finck h = GetClipboardData( CF_TEXT ); 1851c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1852c2c66affSColin Finck h = GetClipboardData( format_id ); 1853c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1854c2c66affSColin Finck h = GetClipboardData( CF_GDIOBJFIRST + 3 ); 1855c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1856c2c66affSColin Finck h = GetClipboardData( CF_PRIVATEFIRST + 7 ); 1857c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1858c2c66affSColin Finck 1859c2c66affSColin Finck r = EmptyClipboard(); 1860c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1861c2c66affSColin Finck text = create_textA(); 1862c2c66affSColin Finck h = SetClipboardData( CF_TEXT, text ); 1863c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h ); 1864c2c66affSColin Finck 1865c2c66affSColin Finck run_process( "handles_open foobar" ); 1866c2c66affSColin Finck 1867c2c66affSColin Finck ok( is_moveable( text ), "expected moveable mem %p\n", text ); 1868c2c66affSColin Finck h = GetClipboardData( CF_TEXT ); 1869c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h ); 1870c2c66affSColin Finck ok( is_moveable( text ), "expected moveable mem %p\n", text ); 1871c2c66affSColin Finck ptr = GlobalLock( h ); 1872c2c66affSColin Finck ok( !strcmp( ptr, "foobar" ), "wrong data '%.8s'\n", ptr ); 1873c2c66affSColin Finck GlobalUnlock( h ); 1874c2c66affSColin Finck 1875c2c66affSColin Finck r = EmptyClipboard(); 1876c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1877c2c66affSColin Finck ok( is_fixed( h ), "expected free mem %p\n", h ); 1878c2c66affSColin Finck ok( is_freed( text ) || broken( is_moveable(text) ), /* w2003, w2008 */ 1879c2c66affSColin Finck "expected free mem %p\n", text ); 1880c2c66affSColin Finck r = CloseClipboard(); 1881c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1882c2c66affSColin Finck 1883c2c66affSColin Finck /* test CF_BITMAP with a DIB section */ 1884c2c66affSColin Finck memset( &bmi, 0, sizeof(bmi) ); 1885c2c66affSColin Finck bmi.bmiHeader.biSize = sizeof( bmi.bmiHeader ); 1886c2c66affSColin Finck bmi.bmiHeader.biWidth = 29; 1887c2c66affSColin Finck bmi.bmiHeader.biHeight = 13; 1888c2c66affSColin Finck bmi.bmiHeader.biPlanes = 1; 1889c2c66affSColin Finck bmi.bmiHeader.biBitCount = 32; 1890c2c66affSColin Finck bitmap = CreateDIBSection( 0, &bmi, DIB_RGB_COLORS, &bits, 0, 0 ); 1891c2c66affSColin Finck 1892c2c66affSColin Finck r = OpenClipboard( hwnd ); 1893c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1894c2c66affSColin Finck r = EmptyClipboard(); 1895c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1896c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap ); 1897c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h ); 1898c2c66affSColin Finck trace( "dibsection %p\n", h ); 1899c2c66affSColin Finck r = CloseClipboard(); 1900c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1901c2c66affSColin Finck 1902c2c66affSColin Finck run_process( "handles_dib dummy" ); 1903c2c66affSColin Finck 1904c2c66affSColin Finck r = OpenClipboard( hwnd ); 1905c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1906c2c66affSColin Finck ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap ); 1907c2c66affSColin Finck r = EmptyClipboard(); 1908c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1909c2c66affSColin Finck ok( !GetObjectType( bitmap ), "expected deleted %p\n", bitmap ); 1910c2c66affSColin Finck r = CloseClipboard(); 1911c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1912c2c66affSColin Finck 1913c2c66affSColin Finck DestroyWindow( hwnd ); 1914c2c66affSColin Finck } 1915c2c66affSColin Finck 1916c2c66affSColin Finck static void test_GetUpdatedClipboardFormats(void) 1917c2c66affSColin Finck { 1918c2c66affSColin Finck BOOL r; 1919c2c66affSColin Finck UINT count, formats[256]; 1920c2c66affSColin Finck 1921c2c66affSColin Finck if (!pGetUpdatedClipboardFormats) 1922c2c66affSColin Finck { 1923c2c66affSColin Finck win_skip( "GetUpdatedClipboardFormats not supported\n" ); 1924c2c66affSColin Finck return; 1925c2c66affSColin Finck } 1926c2c66affSColin Finck 1927c2c66affSColin Finck count = 0xdeadbeef; 1928c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 0, &count ); 1929c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1930c2c66affSColin Finck ok( !count, "wrong count %u\n", count ); 1931c2c66affSColin Finck 1932c2c66affSColin Finck count = 0xdeadbeef; 1933c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 256, &count ); 1934c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1935c2c66affSColin Finck ok( !count, "wrong count %u\n", count ); 1936c2c66affSColin Finck 1937c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1938c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, NULL ); 1939c2c66affSColin Finck ok( !r, "succeeded\n" ); 1940c2c66affSColin Finck ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() ); 1941c2c66affSColin Finck 1942c2c66affSColin Finck count = 0xdeadbeef; 1943c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count ); 1944c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1945c2c66affSColin Finck ok( !count, "wrong count %u\n", count ); 1946c2c66affSColin Finck 1947c2c66affSColin Finck r = OpenClipboard( 0 ); 1948c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1949c2c66affSColin Finck r = EmptyClipboard(); 1950c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1951c2c66affSColin Finck 1952c2c66affSColin Finck count = 0xdeadbeef; 1953c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count ); 1954c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1955c2c66affSColin Finck ok( !count, "wrong count %u\n", count ); 1956c2c66affSColin Finck 1957c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, 0 ); 1958c2c66affSColin Finck 1959c2c66affSColin Finck count = 0xdeadbeef; 1960c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) ); 1961c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count ); 1962c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1963c2c66affSColin Finck ok( count == 1, "wrong count %u\n", count ); 1964c2c66affSColin Finck ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] ); 1965c2c66affSColin Finck ok( formats[1] == 0xcccccccc, "wrong format %u\n", formats[1] ); 1966c2c66affSColin Finck 1967c2c66affSColin Finck SetClipboardData( CF_TEXT, 0 ); 1968c2c66affSColin Finck count = 0xdeadbeef; 1969c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) ); 1970c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count ); 1971c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1972c2c66affSColin Finck ok( count == 2, "wrong count %u\n", count ); 1973c2c66affSColin Finck ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] ); 1974c2c66affSColin Finck ok( formats[1] == CF_TEXT, "wrong format %u\n", formats[1] ); 1975c2c66affSColin Finck ok( formats[2] == 0xcccccccc, "wrong format %u\n", formats[2] ); 1976c2c66affSColin Finck 1977c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1978c2c66affSColin Finck count = 0xdeadbeef; 1979c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 0, &count ); 1980c2c66affSColin Finck ok( !r, "succeeded\n" ); 1981c2c66affSColin Finck ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() ); 1982c2c66affSColin Finck ok( count == 2, "wrong count %u\n", count ); 1983c2c66affSColin Finck 1984c2c66affSColin Finck SetLastError( 0xdeadbeef ); 1985c2c66affSColin Finck count = 0xdeadbeef; 1986c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 1, &count ); 1987c2c66affSColin Finck ok( !r, "succeeded\n" ); 1988c2c66affSColin Finck ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() ); 1989c2c66affSColin Finck ok( count == 2, "wrong count %u\n", count ); 1990c2c66affSColin Finck 1991c2c66affSColin Finck r = CloseClipboard(); 1992c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1993c2c66affSColin Finck 1994c2c66affSColin Finck count = 0xdeadbeef; 1995c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) ); 1996c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count ); 1997c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 1998c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count ); 1999c2c66affSColin Finck ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] ); 2000c2c66affSColin Finck ok( formats[1] == CF_TEXT, "wrong format %u\n", formats[1] ); 2001c2c66affSColin Finck ok( formats[2] == CF_LOCALE, "wrong format %u\n", formats[2] ); 2002c2c66affSColin Finck ok( formats[3] == CF_OEMTEXT, "wrong format %u\n", formats[3] ); 2003c2c66affSColin Finck ok( formats[4] == 0xcccccccc, "wrong format %u\n", formats[4] ); 2004c2c66affSColin Finck 2005c2c66affSColin Finck count = 0xdeadbeef; 2006c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) ); 2007c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 2, &count ); 2008c2c66affSColin Finck ok( !r, "gle %d\n", GetLastError() ); 2009c2c66affSColin Finck ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() ); 2010c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count ); 2011c2c66affSColin Finck ok( formats[0] == 0xcccccccc, "wrong format %u\n", formats[0] ); 2012c2c66affSColin Finck 2013c2c66affSColin Finck count = 0xdeadbeef; 2014c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 256, &count ); 2015c2c66affSColin Finck ok( !r, "gle %d\n", GetLastError() ); 2016c2c66affSColin Finck ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() ); 2017c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count ); 2018c2c66affSColin Finck 2019c2c66affSColin Finck count = 0xdeadbeef; 2020c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 256, &count ); 2021c2c66affSColin Finck ok( !r, "gle %d\n", GetLastError() ); 2022c2c66affSColin Finck ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() ); 2023c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count ); 2024c2c66affSColin Finck } 2025c2c66affSColin Finck 2026c2c66affSColin Finck static const struct 2027c2c66affSColin Finck { 2028c2c66affSColin Finck char strA[12]; 2029c2c66affSColin Finck WCHAR strW[12]; 2030c2c66affSColin Finck UINT len; 2031c2c66affSColin Finck } test_data[] = 2032c2c66affSColin Finck { 2033c2c66affSColin Finck { "foo", {0}, 3 }, /* 0 */ 2034c2c66affSColin Finck { "foo", {0}, 4 }, 2035c2c66affSColin Finck { "foo\0bar", {0}, 7 }, 2036c2c66affSColin Finck { "foo\0bar", {0}, 8 }, 2037c2c66affSColin Finck { "", {'f','o','o'}, 3 * sizeof(WCHAR) }, 2038c2c66affSColin Finck { "", {'f','o','o',0}, 4 * sizeof(WCHAR) }, /* 5 */ 2039c2c66affSColin Finck { "", {'f','o','o',0,'b','a','r'}, 7 * sizeof(WCHAR) }, 2040c2c66affSColin Finck { "", {'f','o','o',0,'b','a','r',0}, 8 * sizeof(WCHAR) }, 2041c2c66affSColin Finck { "", {'f','o','o'}, 1 }, 2042c2c66affSColin Finck { "", {'f','o','o'}, 2 }, 2043c2c66affSColin Finck { "", {'f','o','o'}, 5 }, /* 10 */ 2044c2c66affSColin Finck { "", {'f','o','o',0}, 7 }, 2045c2c66affSColin Finck { "", {'f','o','o',0}, 9 }, 2046c2c66affSColin Finck }; 2047c2c66affSColin Finck 2048c2c66affSColin Finck static void test_string_data(void) 2049c2c66affSColin Finck { 2050c2c66affSColin Finck UINT i; 2051c2c66affSColin Finck BOOL r; 2052c2c66affSColin Finck HANDLE data; 2053c2c66affSColin Finck char cmd[16]; 2054c2c66affSColin Finck char bufferA[12]; 2055c2c66affSColin Finck WCHAR bufferW[12]; 2056c2c66affSColin Finck 2057c2c66affSColin Finck for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++) 2058c2c66affSColin Finck { 2059c2c66affSColin Finck /* 1-byte Unicode strings crash on Win64 */ 2060c2c66affSColin Finck #ifdef _WIN64 2061c2c66affSColin Finck if (!test_data[i].strA[0] && test_data[i].len < sizeof(WCHAR)) continue; 2062c2c66affSColin Finck #endif 2063c2c66affSColin Finck r = OpenClipboard( 0 ); 2064c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 2065c2c66affSColin Finck r = EmptyClipboard(); 2066c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 2067c2c66affSColin Finck data = GlobalAlloc( GMEM_FIXED, test_data[i].len ); 2068c2c66affSColin Finck if (test_data[i].strA[0]) 2069c2c66affSColin Finck { 2070c2c66affSColin Finck memcpy( data, test_data[i].strA, test_data[i].len ); 2071c2c66affSColin Finck SetClipboardData( CF_TEXT, data ); 2072c2c66affSColin Finck memcpy( bufferA, test_data[i].strA, test_data[i].len ); 2073c2c66affSColin Finck bufferA[test_data[i].len - 1] = 0; 2074c2c66affSColin Finck ok( !memcmp( data, bufferA, test_data[i].len ), 2075c2c66affSColin Finck "%u: wrong data %.*s\n", i, test_data[i].len, (char *)data ); 2076c2c66affSColin Finck } 2077c2c66affSColin Finck else 2078c2c66affSColin Finck { 2079c2c66affSColin Finck memcpy( data, test_data[i].strW, test_data[i].len ); 2080c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, data ); 2081c2c66affSColin Finck memcpy( bufferW, test_data[i].strW, test_data[i].len ); 2082c2c66affSColin Finck bufferW[(test_data[i].len + 1) / sizeof(WCHAR) - 1] = 0; 2083c2c66affSColin Finck ok( !memcmp( data, bufferW, test_data[i].len ), 2084c2c66affSColin Finck "%u: wrong data %s\n", i, wine_dbgstr_wn( data, (test_data[i].len + 1) / sizeof(WCHAR) )); 2085c2c66affSColin Finck } 2086c2c66affSColin Finck r = CloseClipboard(); 2087c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 2088c2c66affSColin Finck sprintf( cmd, "string_data %u", i ); 2089c2c66affSColin Finck run_process( cmd ); 2090c2c66affSColin Finck } 2091c2c66affSColin Finck } 2092c2c66affSColin Finck 2093c2c66affSColin Finck static void test_string_data_process( int i ) 2094c2c66affSColin Finck { 2095c2c66affSColin Finck BOOL r; 2096c2c66affSColin Finck HANDLE data; 2097c2c66affSColin Finck UINT len, len2; 2098c2c66affSColin Finck char bufferA[12]; 2099c2c66affSColin Finck WCHAR bufferW[12]; 2100c2c66affSColin Finck 2101c2c66affSColin Finck r = OpenClipboard( 0 ); 2102c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 2103c2c66affSColin Finck if (test_data[i].strA[0]) 2104c2c66affSColin Finck { 2105c2c66affSColin Finck data = GetClipboardData( CF_TEXT ); 2106c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i ); 2107c2c66affSColin Finck len = GlobalSize( data ); 2108c2c66affSColin Finck ok( len == test_data[i].len, "%u: wrong size %u / %u\n", i, len, test_data[i].len ); 2109c2c66affSColin Finck memcpy( bufferA, test_data[i].strA, test_data[i].len ); 2110c2c66affSColin Finck bufferA[test_data[i].len - 1] = 0; 2111c2c66affSColin Finck ok( !memcmp( data, bufferA, len ), "%u: wrong data %.*s\n", i, len, (char *)data ); 2112c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT ); 2113c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i ); 2114c2c66affSColin Finck len = GlobalSize( data ); 2115c2c66affSColin Finck len2 = MultiByteToWideChar( CP_ACP, 0, bufferA, test_data[i].len, bufferW, 12 ); 2116c2c66affSColin Finck ok( len == len2 * sizeof(WCHAR), "%u: wrong size %u / %u\n", i, len, len2 ); 2117c2c66affSColin Finck ok( !memcmp( data, bufferW, len ), "%u: wrong data %s\n", i, wine_dbgstr_wn( data, len2 )); 2118c2c66affSColin Finck } 2119c2c66affSColin Finck else 2120c2c66affSColin Finck { 2121c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT ); 2122c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i ); 2123c2c66affSColin Finck len = GlobalSize( data ); 2124c2c66affSColin Finck ok( len == test_data[i].len, "%u: wrong size %u / %u\n", i, len, test_data[i].len ); 2125c2c66affSColin Finck memcpy( bufferW, test_data[i].strW, test_data[i].len ); 2126c2c66affSColin Finck bufferW[(test_data[i].len + 1) / sizeof(WCHAR) - 1] = 0; 2127c2c66affSColin Finck ok( !memcmp( data, bufferW, len ), 2128c2c66affSColin Finck "%u: wrong data %s\n", i, wine_dbgstr_wn( data, (len + 1) / sizeof(WCHAR) )); 2129c2c66affSColin Finck data = GetClipboardData( CF_TEXT ); 2130c2c66affSColin Finck if (test_data[i].len >= sizeof(WCHAR)) 2131c2c66affSColin Finck { 2132c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i ); 2133c2c66affSColin Finck len = GlobalSize( data ); 2134c2c66affSColin Finck len2 = WideCharToMultiByte( CP_ACP, 0, bufferW, test_data[i].len / sizeof(WCHAR), 2135c2c66affSColin Finck bufferA, 12, NULL, NULL ); 2136c2c66affSColin Finck bufferA[len2 - 1] = 0; 2137c2c66affSColin Finck ok( len == len2, "%u: wrong size %u / %u\n", i, len, len2 ); 2138c2c66affSColin Finck ok( !memcmp( data, bufferA, len ), "%u: wrong data %.*s\n", i, len, (char *)data ); 2139c2c66affSColin Finck } 2140c2c66affSColin Finck else 2141c2c66affSColin Finck { 2142c2c66affSColin Finck ok( !data, "%u: got data for empty string\n", i ); 2143c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_TEXT ), "%u: text not available\n", i ); 2144c2c66affSColin Finck } 2145c2c66affSColin Finck } 2146c2c66affSColin Finck r = CloseClipboard(); 2147c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() ); 2148c2c66affSColin Finck } 2149c2c66affSColin Finck 2150c2c66affSColin Finck START_TEST(clipboard) 2151c2c66affSColin Finck { 2152c2c66affSColin Finck char **argv; 2153c2c66affSColin Finck int argc = winetest_get_mainargs( &argv ); 2154c2c66affSColin Finck HMODULE mod = GetModuleHandleA( "user32" ); 2155c2c66affSColin Finck 2156c2c66affSColin Finck argv0 = argv[0]; 2157c2c66affSColin Finck pAddClipboardFormatListener = (void *)GetProcAddress( mod, "AddClipboardFormatListener" ); 2158c2c66affSColin Finck pRemoveClipboardFormatListener = (void *)GetProcAddress( mod, "RemoveClipboardFormatListener" ); 2159c2c66affSColin Finck pGetUpdatedClipboardFormats = (void *)GetProcAddress( mod, "GetUpdatedClipboardFormats" ); 2160c2c66affSColin Finck 2161c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "set_clipboard_data" )) 2162c2c66affSColin Finck { 2163c2c66affSColin Finck set_clipboard_data_process( atoi( argv[3] )); 2164c2c66affSColin Finck return; 2165c2c66affSColin Finck } 2166c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "grab_clipboard" )) 2167c2c66affSColin Finck { 2168c2c66affSColin Finck grab_clipboard_process( atoi( argv[3] )); 2169c2c66affSColin Finck return; 2170c2c66affSColin Finck } 2171c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "handles" )) 2172c2c66affSColin Finck { 2173c2c66affSColin Finck test_handles_process( argv[3] ); 2174c2c66affSColin Finck return; 2175c2c66affSColin Finck } 2176c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "handles_open" )) 2177c2c66affSColin Finck { 2178c2c66affSColin Finck test_handles_process_open( argv[3] ); 2179c2c66affSColin Finck return; 2180c2c66affSColin Finck } 2181c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "handles_dib" )) 2182c2c66affSColin Finck { 2183c2c66affSColin Finck test_handles_process_dib( argv[3] ); 2184c2c66affSColin Finck return; 2185c2c66affSColin Finck } 2186c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "string_data" )) 2187c2c66affSColin Finck { 2188c2c66affSColin Finck test_string_data_process( atoi( argv[3] )); 2189c2c66affSColin Finck return; 2190c2c66affSColin Finck } 2191c2c66affSColin Finck if (argc == 3 && !strcmp( argv[2], "get_clipboard_data" )) 2192c2c66affSColin Finck { 2193c2c66affSColin Finck get_clipboard_data_process( ); 2194c2c66affSColin Finck return; 2195c2c66affSColin Finck } 2196c2c66affSColin Finck 2197c2c66affSColin Finck test_RegisterClipboardFormatA(); 2198c2c66affSColin Finck test_ClipboardOwner(); 2199c2c66affSColin Finck test_synthesized(); 2200c2c66affSColin Finck test_messages(); 2201c2c66affSColin Finck test_data_handles(); 2202c2c66affSColin Finck test_GetUpdatedClipboardFormats(); 2203c2c66affSColin Finck test_string_data(); 2204c2c66affSColin Finck } 2205