2 * Unit test suite for clipboard functions.
4 * Copyright 2002 Dmitry Timoshkov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
29 static BOOL (WINAPI
*pAddClipboardFormatListener
)(HWND hwnd
);
30 static BOOL (WINAPI
*pRemoveClipboardFormatListener
)(HWND hwnd
);
31 static DWORD (WINAPI
*pGetClipboardSequenceNumber
)(void);
32 static BOOL (WINAPI
*pGetUpdatedClipboardFormats
)( UINT
*formats
, UINT count
, UINT
*out_count
);
34 static int thread_from_line
;
37 static DWORD WINAPI
open_clipboard_thread(LPVOID arg
)
40 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
44 static DWORD WINAPI
empty_clipboard_thread(LPVOID arg
)
46 SetLastError( 0xdeadbeef );
47 ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line
);
48 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
49 thread_from_line
, GetLastError());
53 static DWORD WINAPI
open_and_empty_clipboard_thread(LPVOID arg
)
56 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
57 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
61 static DWORD WINAPI
open_and_empty_clipboard_win_thread(LPVOID arg
)
63 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
64 ok(OpenClipboard(hwnd
), "%u: OpenClipboard failed\n", thread_from_line
);
65 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
69 static DWORD WINAPI
set_clipboard_data_thread(LPVOID arg
)
74 SetLastError( 0xdeadbeef );
75 if (GetClipboardOwner() == hwnd
)
77 SetClipboardData( CF_WAVE
, 0 );
78 ok( IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData failed\n", thread_from_line
);
79 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
80 ok( ret
!= 0, "%u: SetClipboardData failed err %u\n", thread_from_line
, GetLastError() );
81 SetLastError( 0xdeadbeef );
82 ret
= GetClipboardData( CF_WAVE
);
83 ok( !ret
, "%u: GetClipboardData succeeded\n", thread_from_line
);
84 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
85 thread_from_line
, GetLastError());
89 SetClipboardData( CF_WAVE
, 0 );
90 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
91 thread_from_line
, GetLastError());
92 ok( !IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData succeeded\n", thread_from_line
);
93 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
94 ok( !ret
, "%u: SetClipboardData succeeded\n", thread_from_line
);
95 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
96 thread_from_line
, GetLastError());
101 static void set_clipboard_data_process( int arg
)
105 SetLastError( 0xdeadbeef );
108 ok( IsClipboardFormatAvailable( CF_WAVE
), "process %u: CF_WAVE not available\n", arg
);
109 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
110 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
114 SetClipboardData( CF_WAVE
, 0 );
115 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
116 arg
, GetLastError());
117 ok( !IsClipboardFormatAvailable( CF_WAVE
), "process %u: SetClipboardData succeeded\n", arg
);
118 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
119 ok( !ret
, "process %u: SetClipboardData succeeded\n", arg
);
120 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
121 arg
, GetLastError());
125 static void grab_clipboard_process( int arg
)
129 SetLastError( 0xdeadbeef );
130 ret
= OpenClipboard( 0 );
131 ok( ret
, "OpenClipboard failed\n" );
132 ret
= EmptyClipboard();
133 ok( ret
, "EmptyClipboard failed\n" );
136 HANDLE ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
137 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
141 static void run_thread( LPTHREAD_START_ROUTINE func
, void *arg
, int line
)
146 thread_from_line
= line
;
147 thread
= CreateThread(NULL
, 0, func
, arg
, 0, NULL
);
148 ok(thread
!= NULL
, "%u: CreateThread failed with error %d\n", line
, GetLastError());
151 ret
= MsgWaitForMultipleObjectsEx( 1, &thread
, 1000, QS_ALLINPUT
, 0 );
152 if (ret
== WAIT_OBJECT_0
+ 1)
155 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
159 ok(ret
== WAIT_OBJECT_0
, "%u: expected WAIT_OBJECT_0, got %u\n", line
, ret
);
163 static void run_process( const char *args
)
166 PROCESS_INFORMATION info
;
167 STARTUPINFOA startup
;
169 sprintf( cmd
, "%s clipboard %s", argv0
, args
);
170 memset( &startup
, 0, sizeof(startup
) );
171 startup
.cb
= sizeof(startup
);
172 ok( CreateProcessA( NULL
, cmd
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &startup
, &info
),
173 "CreateProcess %s failed\n", cmd
);
175 winetest_wait_child_process( info
.hProcess
);
176 CloseHandle( info
.hProcess
);
177 CloseHandle( info
.hThread
);
180 static WNDPROC old_proc
;
181 static LRESULT CALLBACK
winproc_wrapper( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
183 static int wm_renderallformats
;
184 static int wm_drawclipboard
;
186 DWORD msg_flags
= InSendMessageEx( NULL
);
188 if (!seqno
) seqno
= GetClipboardSequenceNumber();
190 trace( "%p msg %04x\n", hwnd
, msg
);
191 if (!wm_renderallformats
)
193 ok( GetClipboardOwner() == hwnd
, "%04x: wrong owner %p/%p\n", msg
, GetClipboardOwner(), hwnd
);
194 ok( seqno
== GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg
);
198 ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg
, GetClipboardOwner() );
199 ok( seqno
+ 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg
);
201 ok( GetClipboardViewer() == hwnd
, "%04x: wrong viewer %p/%p\n", msg
, GetClipboardViewer(), hwnd
);
202 ok( GetOpenClipboardWindow() == hwnd
, "%04x: wrong open win %p/%p\n",
203 msg
, GetOpenClipboardWindow(), hwnd
);
208 ok( wm_renderallformats
, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
209 ok( wm_drawclipboard
, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
211 case WM_DRAWCLIPBOARD
:
212 ok( msg_flags
== ISMEX_NOSEND
, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
215 case WM_RENDERALLFORMATS
:
216 ok( msg_flags
== ISMEX_NOSEND
, "WM_RENDERALLFORMATS wrong flags %x\n", msg_flags
);
217 wm_renderallformats
++;
220 return old_proc( hwnd
, msg
, wp
, lp
);
223 static void test_ClipboardOwner(void)
228 SetLastError(0xdeadbeef);
229 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
230 "could not perform clipboard test: clipboard already owned\n");
232 hWnd1
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
233 0, 0, 10, 10, 0, 0, 0, NULL
);
234 ok(hWnd1
!= 0, "CreateWindowExA error %d\n", GetLastError());
235 trace("hWnd1 = %p\n", hWnd1
);
237 hWnd2
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
238 0, 0, 10, 10, 0, 0, 0, NULL
);
239 ok(hWnd2
!= 0, "CreateWindowExA error %d\n", GetLastError());
240 trace("hWnd2 = %p\n", hWnd2
);
242 SetLastError(0xdeadbeef);
243 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
244 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
245 "wrong error %u\n", GetLastError());
247 ok(OpenClipboard(0), "OpenClipboard failed\n");
248 ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
249 ok(!OpenClipboard(hWnd1
), "OpenClipboard should fail since clipboard already opened\n");
250 ok(OpenClipboard(0), "OpenClipboard again failed\n");
251 ret
= CloseClipboard();
252 ok( ret
, "CloseClipboard error %d\n", GetLastError());
254 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
255 run_thread( open_clipboard_thread
, hWnd1
, __LINE__
);
256 run_thread( empty_clipboard_thread
, 0, __LINE__
);
257 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
258 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
259 ok( !GetClipboardData( CF_WAVE
), "CF_WAVE data available\n" );
260 run_process( "set_clipboard_data 0" );
261 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
262 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
264 SetLastError(0xdeadbeef);
265 ret
= OpenClipboard(hWnd2
);
266 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
267 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
269 SetLastError(0xdeadbeef);
270 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
271 ret
= EmptyClipboard();
272 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
273 ok(GetClipboardOwner() == hWnd1
, "clipboard should be owned by %p, not by %p\n", hWnd1
, GetClipboardOwner());
274 run_thread( empty_clipboard_thread
, 0, __LINE__
);
275 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
276 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
277 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
278 run_process( "set_clipboard_data 1" );
280 SetLastError(0xdeadbeef);
281 ret
= OpenClipboard(hWnd2
);
282 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
283 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
285 ret
= CloseClipboard();
286 ok( ret
, "CloseClipboard error %d\n", GetLastError());
287 ok(GetClipboardOwner() == hWnd1
, "clipboard should still be owned\n");
289 /* any window will do, even from a different process */
290 ret
= OpenClipboard( GetDesktopWindow() );
291 ok( ret
, "OpenClipboard error %d\n", GetLastError());
292 ret
= EmptyClipboard();
293 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
294 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
295 GetClipboardOwner(), GetDesktopWindow() );
296 run_thread( set_clipboard_data_thread
, GetDesktopWindow(), __LINE__
);
297 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
298 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
299 run_process( "set_clipboard_data 2" );
300 ret
= CloseClipboard();
301 ok( ret
, "CloseClipboard error %d\n", GetLastError());
303 ret
= OpenClipboard( hWnd1
);
304 ok( ret
, "OpenClipboard error %d\n", GetLastError());
305 ret
= EmptyClipboard();
306 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
307 SetClipboardData( CF_WAVE
, 0 );
308 SetClipboardViewer( hWnd1
);
309 ok( GetClipboardOwner() == hWnd1
, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1
);
310 ok( GetClipboardViewer() == hWnd1
, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1
);
311 ok( GetOpenClipboardWindow() == hWnd1
, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1
);
312 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
314 old_proc
= (WNDPROC
)SetWindowLongPtrA( hWnd1
, GWLP_WNDPROC
, (LONG_PTR
)winproc_wrapper
);
315 ret
= DestroyWindow(hWnd1
);
316 ok( ret
, "DestroyWindow error %d\n", GetLastError());
317 ret
= DestroyWindow(hWnd2
);
318 ok( ret
, "DestroyWindow error %d\n", GetLastError());
319 SetLastError(0xdeadbeef);
320 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
321 ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n");
322 ok(!GetOpenClipboardWindow() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n");
323 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
325 SetLastError( 0xdeadbeef );
326 ret
= CloseClipboard();
327 ok( !ret
, "CloseClipboard succeeded\n" );
328 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
330 ret
= OpenClipboard( 0 );
331 ok( ret
, "OpenClipboard error %d\n", GetLastError());
332 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
333 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
334 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
335 run_process( "set_clipboard_data 3" );
336 ret
= CloseClipboard();
337 ok( ret
, "CloseClipboard error %d\n", GetLastError());
339 run_thread( open_and_empty_clipboard_thread
, 0, __LINE__
);
340 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
341 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
343 ret
= OpenClipboard( 0 );
344 ok( ret
, "OpenClipboard error %d\n", GetLastError());
345 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
346 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
347 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
348 run_process( "set_clipboard_data 4" );
349 ret
= EmptyClipboard();
350 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
351 ret
= CloseClipboard();
352 ok( ret
, "CloseClipboard error %d\n", GetLastError());
354 SetLastError( 0xdeadbeef );
355 ok( !SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 )),
356 "SetClipboardData succeeded\n" );
357 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
358 ok( !IsClipboardFormatAvailable( CF_WAVE
), "SetClipboardData succeeded\n" );
360 run_thread( open_and_empty_clipboard_thread
, GetDesktopWindow(), __LINE__
);
361 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
362 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n",
363 GetClipboardOwner(), GetDesktopWindow() );
365 run_thread( open_and_empty_clipboard_win_thread
, 0, __LINE__
);
366 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
367 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
370 static void test_RegisterClipboardFormatA(void)
373 UINT format_id
, format_id2
;
379 format_id
= RegisterClipboardFormatA("my_cool_clipboard_format");
380 ok(format_id
> 0xc000 && format_id
< 0xffff, "invalid clipboard format id %04x\n", format_id
);
382 format_id2
= RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
383 ok(format_id2
== format_id
, "invalid clipboard format id %04x\n", format_id2
);
385 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
386 ok(len
== lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len
);
387 ok(!lstrcmpA(buf
, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf
);
389 lstrcpyA(buf
, "foo");
390 SetLastError(0xdeadbeef);
391 len
= GetAtomNameA((ATOM
)format_id
, buf
, 256);
392 ok(len
== 0, "GetAtomNameA should fail\n");
393 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
397 lstrcpyA(buf
, "foo");
398 SetLastError(0xdeadbeef);
399 len
= GlobalGetAtomNameA((ATOM
)format_id
, buf
, 256);
400 ok(len
== 0, "GlobalGetAtomNameA should fail\n");
401 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
404 SetLastError(0xdeadbeef);
405 atom_id
= FindAtomA("my_cool_clipboard_format");
406 ok(atom_id
== 0, "FindAtomA should fail\n");
407 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
411 /* this relies on the clipboard and global atom table being different */
412 SetLastError(0xdeadbeef);
413 atom_id
= GlobalFindAtomA("my_cool_clipboard_format");
414 ok(atom_id
== 0, "GlobalFindAtomA should fail\n");
415 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
418 for (format_id
= 0; format_id
< 0x10fff; format_id
++)
420 SetLastError(0xdeadbeef);
421 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
423 if (format_id
< 0xc000 || format_id
> 0xffff)
424 ok(!len
, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len
, buf
);
425 else if (len
&& winetest_debug
> 1)
426 trace("%04x: %s\n", format_id
, len
? buf
: "");
429 ret
= OpenClipboard(0);
430 ok( ret
, "OpenClipboard error %d\n", GetLastError());
432 /* try some invalid/unregistered formats */
433 SetLastError( 0xdeadbeef );
434 handle
= SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
435 ok( !handle
, "SetClipboardData succeeded\n" );
436 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError());
437 handle
= SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
438 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
439 handle
= SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
440 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
441 handle
= SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
442 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
444 ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
445 ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
446 ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
447 ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
448 ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
449 ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
451 trace("# of formats available: %d\n", CountClipboardFormats());
454 while ((format_id
= EnumClipboardFormats(format_id
)))
456 ok(IsClipboardFormatAvailable(format_id
), "format %04x was listed as available\n", format_id
);
457 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
458 trace("%04x: %s\n", format_id
, len
? buf
: "");
461 ret
= EmptyClipboard();
462 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
463 ret
=CloseClipboard();
464 ok( ret
, "CloseClipboard error %d\n", GetLastError());
466 if (CountClipboardFormats())
468 SetLastError(0xdeadbeef);
469 ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
470 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
,
471 "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError());
474 SetLastError(0xdeadbeef);
475 ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
476 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
477 "Wrong error %u\n", GetLastError());
479 format_id
= RegisterClipboardFormatA("#1234");
480 ok(format_id
== 1234, "invalid clipboard format id %04x\n", format_id
);
483 static HGLOBAL
create_textA(void)
485 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, 10);
486 char *p
= GlobalLock(h
);
487 memcpy(p
, "test\0\0\0\0\0", 10);
492 static HGLOBAL
create_textW(void)
494 static const WCHAR testW
[] = {'t','e','s','t',0,0,0,0,0,0};
495 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, sizeof(testW
));
496 WCHAR
*p
= GlobalLock(h
);
497 memcpy(p
, testW
, sizeof(testW
));
502 static HANDLE
create_metafile(void)
504 const RECT rect
= {0, 0, 100, 100};
508 HDC hdc
= CreateMetaFileA( NULL
);
509 ExtTextOutA( hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
510 mf
= CloseMetaFile( hdc
);
511 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, sizeof(*pict
) );
512 pict
= GlobalLock( ret
);
514 pict
->xExt
= pict
->yExt
= 100;
520 static HENHMETAFILE
create_emf(void)
522 const RECT rect
= {0, 0, 100, 100};
523 HDC hdc
= CreateEnhMetaFileA(NULL
, NULL
, &rect
, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
524 ExtTextOutA(hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
525 return CloseEnhMetaFile(hdc
);
528 static HBITMAP
create_bitmap(void)
530 HDC hdc
= GetDC( 0 );
531 UINT bpp
= GetDeviceCaps( hdc
, BITSPIXEL
);
533 return CreateBitmap( 10, 10, 1, bpp
, NULL
);
536 static HBITMAP
create_dib( BOOL v5
)
539 BITMAPINFOHEADER
*hdr
;
541 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
| GMEM_ZEROINIT
,
542 sizeof(BITMAPV5HEADER
) + 256 * sizeof(RGBQUAD
) + 16 * 16 * 4 );
543 hdr
= GlobalLock( ret
);
544 hdr
->biSize
= v5
? sizeof(BITMAPV5HEADER
) : sizeof(*hdr
);
548 hdr
->biBitCount
= 32;
549 hdr
->biCompression
= BI_RGB
;
552 BITMAPV5HEADER
*hdr5
= (BITMAPV5HEADER
*)hdr
;
553 hdr5
->bV5RedMask
= 0x0000ff;
554 hdr5
->bV5GreenMask
= 0x00ff00;
555 hdr5
->bV5BlueMask
= 0xff0000;
556 hdr5
->bV5AlphaMask
= 0xff000000;
562 static LRESULT CALLBACK
renderer_winproc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
564 static UINT rendered
;
569 case WM_RENDERFORMAT
:
570 if (wp
< 32) rendered
|= (1 << wp
);
577 return DefWindowProcA( hwnd
, msg
, wp
, lp
);
580 static void test_synthesized(void)
582 static const struct test
588 /* 0 */ { CF_TEXT
, { CF_TEXT
, CF_LOCALE
, CF_OEMTEXT
, CF_UNICODETEXT
}},
589 { CF_OEMTEXT
, { CF_OEMTEXT
, CF_LOCALE
, CF_TEXT
, CF_UNICODETEXT
}},
590 { CF_UNICODETEXT
, { CF_UNICODETEXT
, CF_LOCALE
, CF_TEXT
, CF_OEMTEXT
}},
591 { CF_ENHMETAFILE
, { CF_ENHMETAFILE
, CF_METAFILEPICT
}},
592 { CF_METAFILEPICT
, { CF_METAFILEPICT
, CF_ENHMETAFILE
}},
593 /* 5 */ { CF_BITMAP
, { CF_BITMAP
, CF_DIB
, CF_DIBV5
}},
594 { CF_DIB
, { CF_DIB
, CF_BITMAP
, CF_DIBV5
}},
595 { CF_DIBV5
, { CF_DIBV5
, CF_BITMAP
, CF_DIB
}},
601 UINT cf
, i
, j
, count
, rendered
;
605 hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
606 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)renderer_winproc
);
608 htext
= create_textA();
611 r
= OpenClipboard(NULL
);
612 ok(r
, "gle %d\n", GetLastError());
613 r
= EmptyClipboard();
614 ok(r
, "gle %d\n", GetLastError());
615 h
= SetClipboardData(CF_TEXT
, htext
);
616 ok(h
== htext
, "got %p\n", h
);
617 h
= SetClipboardData(CF_ENHMETAFILE
, emf
);
618 ok(h
== emf
, "got %p\n", h
);
619 r
= CloseClipboard();
620 ok(r
, "gle %d\n", GetLastError());
622 count
= CountClipboardFormats();
623 ok( count
== 6, "count %u\n", count
);
624 r
= IsClipboardFormatAvailable( CF_TEXT
);
625 ok( r
, "CF_TEXT not available err %d\n", GetLastError());
626 r
= IsClipboardFormatAvailable( CF_LOCALE
);
627 ok( r
, "CF_LOCALE not available err %d\n", GetLastError());
628 r
= IsClipboardFormatAvailable( CF_OEMTEXT
);
629 ok( r
, "CF_OEMTEXT not available err %d\n", GetLastError());
630 r
= IsClipboardFormatAvailable( CF_UNICODETEXT
);
631 ok( r
, "CF_UNICODETEXT not available err %d\n", GetLastError());
632 r
= IsClipboardFormatAvailable( CF_ENHMETAFILE
);
633 ok( r
, "CF_ENHMETAFILE not available err %d\n", GetLastError());
634 r
= IsClipboardFormatAvailable( CF_METAFILEPICT
);
635 ok( r
, "CF_METAFILEPICT not available err %d\n", GetLastError());
637 r
= OpenClipboard(NULL
);
638 ok(r
, "gle %d\n", GetLastError());
639 cf
= EnumClipboardFormats(0);
640 ok(cf
== CF_TEXT
, "cf %08x\n", cf
);
641 data
= GetClipboardData(cf
);
642 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
644 cf
= EnumClipboardFormats(cf
);
645 ok(cf
== CF_ENHMETAFILE
, "cf %08x\n", cf
);
646 data
= GetClipboardData(cf
);
647 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
649 cf
= EnumClipboardFormats(cf
);
650 ok(cf
== CF_LOCALE
, "cf %08x\n", cf
);
651 data
= GetClipboardData(cf
);
652 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
654 cf
= EnumClipboardFormats(cf
);
655 ok(cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
656 data
= GetClipboardData(cf
);
657 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
659 cf
= EnumClipboardFormats(cf
);
660 ok(cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
662 cf
= EnumClipboardFormats(cf
);
663 ok(cf
== CF_METAFILEPICT
, "cf %08x\n", cf
);
664 data
= GetClipboardData(cf
);
665 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
667 cf
= EnumClipboardFormats(cf
);
668 ok(cf
== 0, "cf %08x\n", cf
);
670 r
= EmptyClipboard();
671 ok(r
, "gle %d\n", GetLastError());
673 SetClipboardData( CF_UNICODETEXT
, create_textW() );
674 SetClipboardData( CF_TEXT
, create_textA() );
675 SetClipboardData( CF_OEMTEXT
, create_textA() );
676 r
= CloseClipboard();
677 ok(r
, "gle %d\n", GetLastError());
679 r
= OpenClipboard( NULL
);
680 ok(r
, "gle %d\n", GetLastError());
681 SetLastError( 0xdeadbeef );
682 cf
= EnumClipboardFormats(0);
683 ok( cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
684 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
685 SetLastError( 0xdeadbeef );
686 cf
= EnumClipboardFormats(cf
);
687 ok( cf
== CF_TEXT
, "cf %08x\n", cf
);
688 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
689 SetLastError( 0xdeadbeef );
690 cf
= EnumClipboardFormats(cf
);
691 ok( cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
692 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
693 SetLastError( 0xdeadbeef );
694 cf
= EnumClipboardFormats(cf
);
695 ok( cf
== CF_LOCALE
, "cf %08x\n", cf
);
696 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
697 SetLastError( 0xdeadbeef );
698 cf
= EnumClipboardFormats( cf
);
699 ok( cf
== 0, "cf %08x\n", cf
);
700 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
701 SetLastError( 0xdeadbeef );
702 cf
= EnumClipboardFormats( 0xdead );
703 ok( cf
== 0, "cf %08x\n", cf
);
704 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
706 r
= EmptyClipboard();
707 ok(r
, "gle %d\n", GetLastError());
709 r
= CloseClipboard();
710 ok(r
, "gle %d\n", GetLastError());
712 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
714 r
= OpenClipboard(NULL
);
715 ok(r
, "%u: gle %d\n", i
, GetLastError());
716 r
= EmptyClipboard();
717 ok(r
, "%u: gle %d\n", i
, GetLastError());
719 switch (tests
[i
].format
)
723 SetClipboardData( tests
[i
].format
, create_textA() );
726 SetClipboardData( CF_UNICODETEXT
, create_textW() );
729 SetClipboardData( CF_ENHMETAFILE
, create_emf() );
731 case CF_METAFILEPICT
:
732 SetClipboardData( CF_METAFILEPICT
, create_metafile() );
735 SetClipboardData( CF_BITMAP
, create_bitmap() );
739 SetClipboardData( tests
[i
].format
, create_dib( tests
[i
].format
== CF_DIBV5
));
743 count
= CountClipboardFormats();
744 ok( count
== 1, "%u: count %u\n", i
, count
);
746 r
= CloseClipboard();
747 ok(r
, "%u: gle %d\n", i
, GetLastError());
749 count
= CountClipboardFormats();
750 for (j
= 0; tests
[i
].expected
[j
]; j
++)
752 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
753 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
755 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
757 r
= OpenClipboard( hwnd
);
758 ok(r
, "%u: gle %d\n", i
, GetLastError());
760 for (j
= 0; tests
[i
].expected
[j
]; j
++)
762 cf
= EnumClipboardFormats( cf
);
763 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
764 i
, j
, cf
, tests
[i
].expected
[j
] );
765 if (cf
!= tests
[i
].expected
[j
]) break;
766 data
= GetClipboardData( cf
);
768 broken( tests
[i
].format
== CF_DIBV5
&& cf
== CF_DIB
), /* >= Vista */
769 "%u: couldn't get data, cf %04x err %d\n", i
, cf
, GetLastError());
774 UINT
*ptr
= GlobalLock( data
);
775 ok( GlobalSize( data
) == sizeof(*ptr
), "%u: size %lu\n", i
, GlobalSize( data
));
776 ok( *ptr
== GetUserDefaultLCID() ||
777 broken( *ptr
== MAKELANGID( LANG_ENGLISH
, SUBLANG_DEFAULT
)),
778 "%u: CF_LOCALE %08x/%08x\n", i
, *ptr
, GetUserDefaultLCID() );
779 GlobalUnlock( data
);
784 ok( GlobalSize( data
) == 10, "wrong len %ld\n", GlobalSize( data
));
787 ok( GlobalSize( data
) == 10 * sizeof(WCHAR
), "wrong len %ld\n", GlobalSize( data
));
791 if (!tests
[i
].expected
[j
])
793 cf
= EnumClipboardFormats( cf
);
794 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
797 /* now with delayed rendering */
799 r
= EmptyClipboard();
800 ok(r
, "%u: gle %d\n", i
, GetLastError());
802 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
803 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
805 SetClipboardData( tests
[i
].format
, 0 );
806 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
807 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
809 count
= CountClipboardFormats();
810 ok( count
== 1, "%u: count %u\n", i
, count
);
812 r
= CloseClipboard();
813 ok(r
, "%u: gle %d\n", i
, GetLastError());
814 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
815 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
817 count
= CountClipboardFormats();
818 for (j
= 0; tests
[i
].expected
[j
]; j
++)
820 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
821 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
823 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
824 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
825 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
827 r
= OpenClipboard(NULL
);
828 ok(r
, "%u: gle %d\n", i
, GetLastError());
830 for (j
= 0; tests
[i
].expected
[j
]; j
++)
832 cf
= EnumClipboardFormats( cf
);
833 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
834 i
, j
, cf
, tests
[i
].expected
[j
] );
835 if (cf
!= tests
[i
].expected
[j
]) break;
836 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
837 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
838 data
= GetClipboardData( cf
);
839 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
842 ok(data
!= NULL
, "%u: CF_LOCALE no data\n", i
);
843 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
847 ok(!data
, "%u: format %04x got data %p\n", i
, cf
, data
);
848 ok( rendered
== (1 << tests
[i
].format
),
849 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
850 /* try to render a second time */
851 data
= GetClipboardData( cf
);
852 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
853 ok( rendered
== (1 << tests
[i
].format
),
854 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
857 if (!tests
[i
].expected
[j
])
859 cf
= EnumClipboardFormats( cf
);
860 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
862 r
= CloseClipboard();
863 ok(r
, "%u: gle %d\n", i
, GetLastError());
864 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
865 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
868 r
= OpenClipboard(NULL
);
869 ok(r
, "gle %d\n", GetLastError());
870 r
= EmptyClipboard();
871 ok(r
, "gle %d\n", GetLastError());
872 r
= CloseClipboard();
873 ok(r
, "gle %d\n", GetLastError());
874 DestroyWindow( hwnd
);
877 static CRITICAL_SECTION clipboard_cs
;
878 static HWND next_wnd
;
879 static UINT wm_drawclipboard
;
880 static UINT wm_clipboardupdate
;
881 static UINT wm_destroyclipboard
;
882 static UINT wm_renderformat
;
883 static UINT nb_formats
;
884 static BOOL cross_thread
;
886 static LRESULT CALLBACK
clipboard_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
889 DWORD msg_flags
= InSendMessageEx( NULL
);
892 case WM_DRAWCLIPBOARD
:
893 ok( msg_flags
== (cross_thread
? ISMEX_NOTIFY
: ISMEX_NOSEND
),
894 "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
895 EnterCriticalSection(&clipboard_cs
);
897 LeaveCriticalSection(&clipboard_cs
);
899 case WM_CHANGECBCHAIN
:
900 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
901 "WM_CHANGECBCHAIN wrong flags %x\n", msg_flags
);
902 if (next_wnd
== (HWND
)wp
)
905 SendMessageA(next_wnd
, msg
, wp
, lp
);
907 case WM_DESTROYCLIPBOARD
:
908 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
909 "WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags
);
910 wm_destroyclipboard
++;
911 ok( GetClipboardOwner() == hwnd
, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
912 nb_formats
= CountClipboardFormats();
914 case WM_RENDERFORMAT
:
915 ok( !wm_renderformat
, "multiple WM_RENDERFORMAT %04x / %04lx\n", wm_renderformat
, wp
);
916 wm_renderformat
= wp
;
918 case WM_CLIPBOARDUPDATE
:
919 ok( msg_flags
== ISMEX_NOSEND
, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags
);
920 EnterCriticalSection(&clipboard_cs
);
921 wm_clipboardupdate
++;
922 LeaveCriticalSection(&clipboard_cs
);
925 ChangeClipboardChain(hwnd
, next_wnd
);
929 ret
= wm_drawclipboard
;
930 wm_drawclipboard
= 0;
933 ret
= wm_clipboardupdate
;
934 wm_clipboardupdate
= 0;
937 ret
= wm_destroyclipboard
;
938 wm_destroyclipboard
= 0;
941 ret
= wm_renderformat
;
948 return DefWindowProcA(hwnd
, msg
, wp
, lp
);
951 static DWORD WINAPI
clipboard_thread(void *param
)
953 HWND ret
, win
= param
;
957 UINT count
, fmt
, formats
, old_seq
= 0, seq
;
959 cross_thread
= (GetWindowThreadProcessId( win
, NULL
) != GetCurrentThreadId());
960 trace( "%s-threaded test\n", cross_thread
? "multi" : "single" );
962 if (pGetClipboardSequenceNumber
) old_seq
= pGetClipboardSequenceNumber();
964 EnterCriticalSection(&clipboard_cs
);
965 SetLastError(0xdeadbeef);
966 next_wnd
= SetClipboardViewer(win
);
967 ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
968 LeaveCriticalSection(&clipboard_cs
);
970 SetLastError( 0xdeadbeef );
971 ret
= SetClipboardViewer( (HWND
)0xdead );
972 ok( !ret
, "SetClipboardViewer succeeded\n" );
973 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
974 SetLastError( 0xdeadbeef );
975 r
= ChangeClipboardChain( win
, (HWND
)0xdead );
976 ok( !r
, "ChangeClipboardChain succeeded\n" );
977 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
978 SetLastError( 0xdeadbeef );
979 r
= ChangeClipboardChain( (HWND
)0xdead, next_wnd
);
980 ok( !r
, "ChangeClipboardChain succeeded\n" );
981 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
983 if (pAddClipboardFormatListener
)
985 r
= pAddClipboardFormatListener(win
);
986 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
987 SetLastError( 0xdeadbeef );
988 r
= pAddClipboardFormatListener( win
);
989 ok( !r
, "AddClipboardFormatListener succeeded\n" );
990 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
991 SetLastError( 0xdeadbeef );
992 r
= pAddClipboardFormatListener( (HWND
)0xdead );
993 ok( !r
, "AddClipboardFormatListener succeeded\n" );
994 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
995 r
= pAddClipboardFormatListener( GetDesktopWindow() );
996 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
997 r
= pRemoveClipboardFormatListener( GetDesktopWindow() );
998 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1001 if (pGetClipboardSequenceNumber
)
1003 seq
= pGetClipboardSequenceNumber();
1004 ok( seq
== old_seq
, "sequence changed\n" );
1008 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1009 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1010 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1011 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1013 count
= SendMessageA( win
, WM_USER
+ 1, 0, 0 );
1014 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1015 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1016 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1017 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1018 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1020 SetLastError( 0xdeadbeef );
1021 r
= OpenClipboard( (HWND
)0xdead );
1022 ok( !r
, "OpenClipboard succeeded\n" );
1023 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1025 r
= OpenClipboard(win
);
1026 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1028 if (pGetClipboardSequenceNumber
)
1030 seq
= pGetClipboardSequenceNumber();
1031 ok( seq
== old_seq
, "sequence changed\n" );
1035 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1036 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1037 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1038 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1040 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1041 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1042 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1043 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1044 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1045 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1047 r
= EmptyClipboard();
1048 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1050 if (pGetClipboardSequenceNumber
)
1052 seq
= pGetClipboardSequenceNumber();
1053 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1058 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1059 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1060 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1061 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1063 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1064 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1065 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1066 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1067 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1068 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1069 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1070 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1072 r
= EmptyClipboard();
1073 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1074 /* sequence changes again, even though it was already empty */
1075 if (pGetClipboardSequenceNumber
)
1077 seq
= pGetClipboardSequenceNumber();
1078 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1083 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1084 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1085 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1086 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1088 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1089 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1090 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1091 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1092 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1093 ok( count
, "WM_DESTROYCLIPBOARD not received\n" );
1094 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1095 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1096 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1097 ok( !count
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1099 handle
= SetClipboardData( CF_TEXT
, create_textA() );
1100 ok(handle
!= 0, "SetClipboardData failed: %d\n", GetLastError());
1102 if (pGetClipboardSequenceNumber
)
1104 seq
= pGetClipboardSequenceNumber();
1105 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1110 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1111 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1112 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1113 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1115 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1116 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1117 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1118 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1119 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1120 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1122 SetClipboardData( CF_UNICODETEXT
, 0 );
1124 if (pGetClipboardSequenceNumber
)
1126 seq
= pGetClipboardSequenceNumber();
1127 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1132 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1133 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1134 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1135 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1137 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1138 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1139 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1140 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1141 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1142 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1144 SetClipboardData( CF_UNICODETEXT
, 0 ); /* same data again */
1146 if (pGetClipboardSequenceNumber
)
1148 seq
= pGetClipboardSequenceNumber();
1149 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1154 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1155 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1156 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1157 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1159 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1160 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1161 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1162 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1163 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1164 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1166 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1167 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1168 ok( !IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1170 EnterCriticalSection(&clipboard_cs
);
1171 r
= CloseClipboard();
1172 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1173 LeaveCriticalSection(&clipboard_cs
);
1175 if (pGetClipboardSequenceNumber
)
1177 seq
= pGetClipboardSequenceNumber();
1178 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1183 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1184 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1185 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1186 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1188 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1189 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1190 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1191 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1192 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1193 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1195 r
= OpenClipboard(win
);
1196 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1198 if (pGetClipboardSequenceNumber
)
1200 seq
= pGetClipboardSequenceNumber();
1201 ok( seq
== old_seq
, "sequence changed\n" );
1205 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1206 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1207 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1209 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1210 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1211 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1212 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1213 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1214 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1216 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1217 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1218 ok( IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1220 ok( GetClipboardOwner() == win
, "wrong owner %p\n", GetClipboardOwner());
1221 handle
= GetClipboardData( CF_UNICODETEXT
);
1222 ok( !handle
, "got data for CF_UNICODETEXT\n" );
1223 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1224 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1226 handle
= GetClipboardData( CF_OEMTEXT
);
1227 ok( !handle
, "got data for CF_OEMTEXT\n" );
1228 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1229 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1231 SetClipboardData( CF_WAVE
, 0 );
1232 if (pGetClipboardSequenceNumber
)
1234 seq
= pGetClipboardSequenceNumber();
1235 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1240 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1241 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1242 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1243 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1245 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1246 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1247 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1248 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1249 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1250 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1252 r
= CloseClipboard();
1253 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1254 if (pGetClipboardSequenceNumber
)
1256 /* no synthesized format, so CloseClipboard doesn't change the sequence */
1257 seq
= pGetClipboardSequenceNumber();
1258 ok( seq
== old_seq
, "sequence changed\n" );
1263 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1264 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1265 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1266 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1268 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1269 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1270 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1271 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1272 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1273 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1275 r
= OpenClipboard(win
);
1276 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1277 r
= CloseClipboard();
1278 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1279 /* nothing changed */
1280 if (pGetClipboardSequenceNumber
)
1282 seq
= pGetClipboardSequenceNumber();
1283 ok( seq
== old_seq
, "sequence changed\n" );
1287 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1288 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1289 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1290 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1292 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1293 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1294 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1295 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1296 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1297 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1298 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1299 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1301 formats
= CountClipboardFormats();
1302 r
= OpenClipboard(0);
1303 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1304 r
= EmptyClipboard();
1305 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1306 r
= CloseClipboard();
1307 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1311 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1312 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1313 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1314 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1316 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1317 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1318 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1319 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1320 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1321 ok( count
== 1, "WM_DESTROYCLIPBOARD not received\n" );
1322 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1323 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1324 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1325 ok( count
== formats
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1327 r
= OpenClipboard(win
);
1328 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1329 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1330 if (pGetClipboardSequenceNumber
)
1332 seq
= pGetClipboardSequenceNumber();
1333 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1338 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1339 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1340 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1341 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1343 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1344 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1345 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1346 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1347 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1348 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1349 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1350 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1352 EnterCriticalSection(&clipboard_cs
);
1353 r
= CloseClipboard();
1354 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1355 LeaveCriticalSection(&clipboard_cs
);
1357 if (pGetClipboardSequenceNumber
)
1359 seq
= pGetClipboardSequenceNumber();
1360 ok( seq
== old_seq
, "sequence changed\n" );
1365 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1366 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1367 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1368 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1370 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1371 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1372 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1373 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1374 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1375 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1377 run_process( "grab_clipboard 0" );
1379 if (pGetClipboardSequenceNumber
)
1381 seq
= pGetClipboardSequenceNumber();
1382 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1387 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1388 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1389 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1390 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1391 cross_thread
= TRUE
;
1392 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1393 cross_thread
= FALSE
;
1395 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1396 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1397 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1398 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1399 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1400 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1402 r
= OpenClipboard(0);
1403 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1404 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1405 if (pGetClipboardSequenceNumber
)
1407 seq
= pGetClipboardSequenceNumber();
1408 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1413 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1414 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1415 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1416 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1418 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1419 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1420 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1421 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1422 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1423 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1425 EnterCriticalSection(&clipboard_cs
);
1426 r
= CloseClipboard();
1427 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1428 LeaveCriticalSection(&clipboard_cs
);
1430 if (pGetClipboardSequenceNumber
)
1432 seq
= pGetClipboardSequenceNumber();
1433 ok( seq
== old_seq
, "sequence changed\n" );
1438 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD received\n" );
1439 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1440 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1441 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1443 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1444 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1445 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1446 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1447 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1448 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1450 run_process( "grab_clipboard 1" );
1452 if (pGetClipboardSequenceNumber
)
1454 seq
= pGetClipboardSequenceNumber();
1455 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1460 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1461 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1462 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1463 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1464 cross_thread
= TRUE
;
1465 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1466 cross_thread
= FALSE
;
1468 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1469 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1470 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1471 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1472 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1473 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1475 r
= OpenClipboard(0);
1476 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1477 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1478 if (pGetClipboardSequenceNumber
)
1480 seq
= pGetClipboardSequenceNumber();
1481 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1486 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1487 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1488 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1489 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1491 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1492 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1493 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1494 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1495 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1496 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1498 EnterCriticalSection(&clipboard_cs
);
1499 r
= CloseClipboard();
1500 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1501 LeaveCriticalSection(&clipboard_cs
);
1503 if (pGetClipboardSequenceNumber
)
1505 seq
= pGetClipboardSequenceNumber();
1506 ok( seq
== old_seq
, "sequence changed\n" );
1511 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1512 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1513 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1514 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1516 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1517 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1518 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1519 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1520 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1521 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1523 r
= PostMessageA(win
, WM_USER
, 0, 0);
1524 ok(r
, "PostMessage failed: %d\n", GetLastError());
1526 if (pRemoveClipboardFormatListener
)
1528 r
= pRemoveClipboardFormatListener(win
);
1529 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1530 SetLastError( 0xdeadbeef );
1531 r
= pRemoveClipboardFormatListener(win
);
1532 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1533 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1534 SetLastError( 0xdeadbeef );
1535 r
= pRemoveClipboardFormatListener( (HWND
)0xdead );
1536 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1537 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1542 static void test_messages(void)
1550 InitializeCriticalSection(&clipboard_cs
);
1552 memset(&cls
, 0, sizeof(cls
));
1553 cls
.lpfnWndProc
= clipboard_wnd_proc
;
1554 cls
.hInstance
= GetModuleHandleA(NULL
);
1555 cls
.lpszClassName
= "clipboard_test";
1556 RegisterClassA(&cls
);
1558 win
= CreateWindowA("clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0);
1559 ok(win
!= NULL
, "CreateWindow failed: %d\n", GetLastError());
1561 thread
= CreateThread(NULL
, 0, clipboard_thread
, (void*)win
, 0, &tid
);
1562 ok(thread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1564 while(GetMessageA(&msg
, NULL
, 0, 0))
1566 ok( msg
.message
!= WM_DRAWCLIPBOARD
, "WM_DRAWCLIPBOARD was posted\n" );
1567 TranslateMessage(&msg
);
1568 DispatchMessageA(&msg
);
1571 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
1572 CloseHandle(thread
);
1574 DestroyWindow( win
);
1576 /* same tests again but inside a single thread */
1578 win
= CreateWindowA( "clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0 );
1579 ok( win
!= NULL
, "CreateWindow failed: %d\n", GetLastError() );
1581 clipboard_thread( win
);
1582 DestroyWindow( win
);
1584 UnregisterClassA("clipboard_test", GetModuleHandleA(NULL
));
1585 DeleteCriticalSection(&clipboard_cs
);
1588 static BOOL
is_moveable( HANDLE handle
)
1590 void *ptr
= GlobalLock( handle
);
1591 if (ptr
) GlobalUnlock( handle
);
1592 return ptr
&& ptr
!= handle
;
1595 static BOOL
is_fixed( HANDLE handle
)
1597 void *ptr
= GlobalLock( handle
);
1598 if (ptr
) GlobalUnlock( handle
);
1599 return ptr
&& ptr
== handle
;
1602 static BOOL
is_freed( HANDLE handle
)
1604 return !GlobalSize( handle
);
1607 static UINT format_id
;
1608 static HBITMAP bitmap
, bitmap2
;
1609 static HPALETTE palette
;
1610 static const LOGPALETTE logpalette
= { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}};
1612 static void test_handles( HWND hwnd
)
1614 HGLOBAL h
, htext
, htext2
, htext3
, htext4
, htext5
;
1615 HGLOBAL hfixed
, hfixed2
, hmoveable
, empty_fixed
, empty_moveable
;
1617 UINT format_id2
= RegisterClipboardFormatA( "another format" );
1620 HBITMAP bitmap_temp
;
1622 BOOL is_owner
= (GetWindowThreadProcessId( hwnd
, &process
) && process
== GetCurrentProcessId());
1624 trace( "hwnd %p\n", hwnd
);
1625 htext
= create_textA();
1626 htext2
= create_textA();
1627 htext3
= create_textA();
1628 htext4
= create_textA();
1629 htext5
= create_textA();
1630 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
1631 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
1632 palette
= CreatePalette( &logpalette
);
1634 hfixed
= GlobalAlloc( GMEM_FIXED
, 17 );
1635 hfixed2
= GlobalAlloc( GMEM_FIXED
, 17 );
1636 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1637 ok( GlobalSize( hfixed
) == 17, "wrong size %lu\n", GlobalSize( hfixed
));
1639 hmoveable
= GlobalAlloc( GMEM_MOVEABLE
, 23 );
1640 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1641 ok( GlobalSize( hmoveable
) == 23, "wrong size %lu\n", GlobalSize( hmoveable
));
1643 empty_fixed
= GlobalAlloc( GMEM_FIXED
, 0 );
1644 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1646 empty_moveable
= GlobalAlloc( GMEM_MOVEABLE
, 0 );
1647 /* discarded handles can't be GlobalLock'ed */
1648 ok( is_freed( empty_moveable
), "expected free mem %p\n", empty_moveable
);
1650 r
= OpenClipboard( hwnd
);
1651 ok( r
, "gle %d\n", GetLastError() );
1652 r
= EmptyClipboard();
1653 ok( r
, "gle %d\n", GetLastError() );
1655 h
= SetClipboardData( CF_TEXT
, htext
);
1656 ok( h
== htext
, "got %p\n", h
);
1657 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1658 h
= SetClipboardData( format_id
, htext2
);
1659 ok( h
== htext2
, "got %p\n", h
);
1660 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1661 bitmap_temp
= CreateBitmap( 10, 10, 1, 1, NULL
);
1662 h
= SetClipboardData( CF_BITMAP
, bitmap_temp
);
1663 ok( h
== bitmap_temp
, "got %p\n", h
);
1664 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1665 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1666 ok( h
== bitmap
, "got %p\n", h
);
1667 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1668 ok( !GetObjectType( bitmap_temp
), "expected free object %p\n", bitmap_temp
);
1669 h
= SetClipboardData( CF_DSPBITMAP
, bitmap2
);
1670 ok( h
== bitmap2
, "got %p\n", h
);
1671 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1672 h
= SetClipboardData( CF_PALETTE
, palette
);
1673 ok( h
== palette
, "got %p\n", h
);
1674 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1675 h
= SetClipboardData( CF_GDIOBJFIRST
+ 3, htext3
);
1676 ok( h
== htext3
, "got %p\n", h
);
1677 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1678 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, htext5
);
1679 ok( h
== htext5
, "got %p\n", h
);
1680 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1681 h
= SetClipboardData( format_id2
, empty_moveable
);
1682 ok( !h
, "got %p\n", h
);
1683 GlobalFree( empty_moveable
);
1685 if (0) /* crashes on vista64 */
1687 ptr
= HeapAlloc( GetProcessHeap(), 0, 0 );
1688 h
= SetClipboardData( format_id2
, ptr
);
1689 ok( !h
, "got %p\n", h
);
1690 HeapFree( GetProcessHeap(), 0, ptr
);
1693 h
= SetClipboardData( format_id2
, empty_fixed
);
1694 ok( h
== empty_fixed
, "got %p\n", h
);
1695 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1696 h
= SetClipboardData( 0xdeadbeef, hfixed2
);
1697 ok( h
== hfixed2
, "got %p\n", h
);
1698 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1699 h
= SetClipboardData( 0xdeadbabe, hmoveable
);
1700 ok( h
== hmoveable
, "got %p\n", h
);
1701 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1703 ptr
= HeapAlloc( GetProcessHeap(), 0, 37 );
1704 h
= SetClipboardData( 0xdeadfade, ptr
);
1705 ok( h
== ptr
|| !h
, "got %p\n", h
);
1706 if (!h
) /* heap blocks are rejected on >= win8 */
1708 HeapFree( GetProcessHeap(), 0, ptr
);
1712 data
= GetClipboardData( CF_TEXT
);
1713 ok( data
== htext
, "wrong data %p\n", data
);
1714 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1716 data
= GetClipboardData( format_id
);
1717 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1718 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1720 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1721 ok( data
== htext3
, "wrong data %p\n", data
);
1722 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1724 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1725 ok( data
== htext5
, "wrong data %p\n", data
);
1726 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1728 data
= GetClipboardData( format_id2
);
1729 ok( data
== empty_fixed
, "wrong data %p\n", data
);
1730 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1732 data
= GetClipboardData( 0xdeadbeef );
1733 ok( data
== hfixed2
, "wrong data %p\n", data
);
1734 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1736 data
= GetClipboardData( 0xdeadbabe );
1737 ok( data
== hmoveable
, "wrong data %p\n", data
);
1738 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1740 data
= GetClipboardData( 0xdeadfade );
1741 ok( data
== ptr
, "wrong data %p\n", data
);
1743 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, htext4
);
1744 ok( h
== htext4
, "got %p\n", h
);
1745 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1746 ok( is_freed( htext5
), "expected freed mem %p\n", htext5
);
1748 h
= SetClipboardData( 0xdeadbeef, hfixed
);
1749 ok( h
== hfixed
, "got %p\n", h
);
1750 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1752 /* testing if hfixed2 is freed triggers an exception on Win64 */
1753 ok( is_freed( hfixed2
) || broken( !is_freed( hfixed2
)) /* < Vista */, "expected freed mem %p\n", hfixed2
);
1756 r
= CloseClipboard();
1757 ok( r
, "gle %d\n", GetLastError() );
1759 /* data handles are still valid */
1760 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1761 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext2
);
1762 ok( is_moveable( htext3
), "expected moveable mem %p\n", htext3
);
1763 ok( is_moveable( htext4
), "expected moveable mem %p\n", htext4
);
1764 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1765 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1766 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1767 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1768 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1769 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1771 r
= OpenClipboard( hwnd
);
1772 ok( r
, "gle %d\n", GetLastError() );
1774 /* and now they are freed, unless we are the owner */
1777 ok( is_freed( htext
), "expected freed mem %p\n", htext
);
1778 ok( is_freed( htext2
), "expected freed mem %p\n", htext2
);
1779 ok( is_freed( htext3
), "expected freed mem %p\n", htext3
);
1780 ok( is_freed( htext4
), "expected freed mem %p\n", htext4
);
1781 ok( is_freed( hmoveable
), "expected freed mem %p\n", hmoveable
);
1783 data
= GetClipboardData( CF_TEXT
);
1784 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1786 data
= GetClipboardData( format_id
);
1787 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1789 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1790 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1792 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1793 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1795 data
= GetClipboardData( format_id2
);
1796 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1797 ok( GlobalSize( data
) == 1, "wrong size %lu\n", GlobalSize( data
));
1799 data
= GetClipboardData( 0xdeadbeef );
1800 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1801 ok( GlobalSize( data
) == 17, "wrong size %lu\n", GlobalSize( data
));
1803 data
= GetClipboardData( 0xdeadbabe );
1804 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1805 ok( GlobalSize( data
) == 23, "wrong size %lu\n", GlobalSize( data
));
1807 data
= GetClipboardData( 0xdeadfade );
1808 ok( is_fixed( data
) || !ptr
, "expected fixed mem %p\n", data
);
1809 if (ptr
) ok( GlobalSize( data
) == 37, "wrong size %lu\n", GlobalSize( data
));
1813 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1814 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext2
);
1815 ok( is_moveable( htext3
), "expected moveable mem %p\n", htext3
);
1816 ok( is_moveable( htext4
), "expected moveable mem %p\n", htext4
);
1817 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1819 data
= GetClipboardData( CF_TEXT
);
1820 ok( data
== htext
, "wrong data %p\n", data
);
1822 data
= GetClipboardData( format_id
);
1823 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1825 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1826 ok( data
== htext3
, "wrong data %p\n", data
);
1828 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1829 ok( data
== htext4
, "wrong data %p\n", data
);
1831 data
= GetClipboardData( format_id2
);
1832 ok( data
== empty_fixed
, "wrong data %p\n", data
);
1834 data
= GetClipboardData( 0xdeadbeef );
1835 ok( data
== hfixed
, "wrong data %p\n", data
);
1837 data
= GetClipboardData( 0xdeadbabe );
1838 ok( data
== hmoveable
, "wrong data %p\n", data
);
1840 data
= GetClipboardData( 0xdeadfade );
1841 ok( data
== ptr
, "wrong data %p\n", data
);
1844 data
= GetClipboardData( CF_OEMTEXT
);
1845 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1846 data
= GetClipboardData( CF_UNICODETEXT
);
1847 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1848 data
= GetClipboardData( CF_LOCALE
);
1849 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1850 data
= GetClipboardData( CF_BITMAP
);
1851 ok( data
== bitmap
, "expected bitmap %p\n", data
);
1852 data
= GetClipboardData( CF_DSPBITMAP
);
1853 ok( data
== bitmap2
, "expected bitmap %p\n", data
);
1854 data
= GetClipboardData( CF_PALETTE
);
1855 ok( data
== palette
, "expected palette %p\n", data
);
1856 data
= GetClipboardData( CF_DIB
);
1857 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1858 data
= GetClipboardData( CF_DIBV5
);
1859 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1861 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1862 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1863 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1864 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1865 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1867 r
= EmptyClipboard();
1868 ok( r
, "gle %d\n", GetLastError() );
1870 /* w2003, w2008 don't seem to free the data here */
1871 ok( is_freed( htext
) || broken( !is_freed( htext
)), "expected freed mem %p\n", htext
);
1872 ok( is_freed( htext2
) || broken( !is_freed( htext2
)), "expected freed mem %p\n", htext2
);
1873 ok( is_freed( htext3
) || broken( !is_freed( htext3
)), "expected freed mem %p\n", htext3
);
1874 ok( is_freed( htext4
) || broken( !is_freed( htext4
)), "expected freed mem %p\n", htext4
);
1875 ok( is_freed( hmoveable
) || broken( !is_freed( hmoveable
)), "expected freed mem %p\n", hmoveable
);
1876 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1877 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1878 ok( !GetObjectType( bitmap
), "expected freed handle %p\n", bitmap
);
1879 ok( !GetObjectType( bitmap2
), "expected freed handle %p\n", bitmap2
);
1880 ok( !GetObjectType( palette
), "expected freed handle %p\n", palette
);
1882 r
= CloseClipboard();
1883 ok( r
, "gle %d\n", GetLastError() );
1886 static DWORD WINAPI
test_handles_thread( void *arg
)
1888 trace( "running from different thread\n" );
1889 test_handles( (HWND
)arg
);
1893 static DWORD WINAPI
test_handles_thread2( void *arg
)
1899 r
= OpenClipboard( 0 );
1900 ok( r
, "gle %d\n", GetLastError() );
1901 h
= GetClipboardData( CF_TEXT
);
1902 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1903 ptr
= GlobalLock( h
);
1904 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1906 h
= GetClipboardData( format_id
);
1907 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1908 ptr
= GlobalLock( h
);
1909 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1911 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1912 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1913 ptr
= GlobalLock( h
);
1914 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1916 trace( "gdiobj %p\n", h
);
1917 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1918 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1919 ptr
= GlobalLock( h
);
1920 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1922 trace( "private %p\n", h
);
1923 h
= GetClipboardData( CF_BITMAP
);
1924 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1925 ok( h
== bitmap
, "different bitmap %p / %p\n", h
, bitmap
);
1926 trace( "bitmap %p\n", h
);
1927 h
= GetClipboardData( CF_DSPBITMAP
);
1928 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1929 ok( h
== bitmap2
, "different bitmap %p / %p\n", h
, bitmap2
);
1930 trace( "bitmap2 %p\n", h
);
1931 h
= GetClipboardData( CF_PALETTE
);
1932 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1933 ok( h
== palette
, "different palette %p / %p\n", h
, palette
);
1934 trace( "palette %p\n", h
);
1935 h
= GetClipboardData( CF_DIB
);
1936 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1937 h
= GetClipboardData( CF_DIBV5
);
1938 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1939 r
= CloseClipboard();
1940 ok( r
, "gle %d\n", GetLastError() );
1944 static void test_handles_process( const char *str
)
1953 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
1954 r
= OpenClipboard( 0 );
1955 ok( r
, "gle %d\n", GetLastError() );
1956 h
= GetClipboardData( CF_TEXT
);
1957 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1958 ptr
= GlobalLock( h
);
1959 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1961 h
= GetClipboardData( format_id
);
1962 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1963 ptr
= GlobalLock( h
);
1964 if (ptr
) ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1966 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1967 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1968 ptr
= GlobalLock( h
);
1969 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1971 trace( "gdiobj %p\n", h
);
1972 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1973 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1974 ptr
= GlobalLock( h
);
1975 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1977 trace( "private %p\n", h
);
1978 h
= GetClipboardData( CF_BITMAP
);
1979 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1980 ok( GetObjectW( h
, sizeof(bm
), &bm
) == sizeof(bm
), "GetObject %p failed\n", h
);
1981 ok( bm
.bmWidth
== 13 && bm
.bmHeight
== 17, "wrong bitmap %ux%u\n", bm
.bmWidth
, bm
.bmHeight
);
1982 trace( "bitmap %p\n", h
);
1983 h
= GetClipboardData( CF_DSPBITMAP
);
1984 ok( !GetObjectType( h
), "expected invalid object %p\n", h
);
1985 trace( "bitmap2 %p\n", h
);
1986 h
= GetClipboardData( CF_PALETTE
);
1987 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1988 ok( GetPaletteEntries( h
, 0, 1, &entry
) == 1, "GetPaletteEntries %p failed\n", h
);
1989 ok( entry
.peRed
== 0x12 && entry
.peGreen
== 0x34 && entry
.peBlue
== 0x56,
1990 "wrong color %02x,%02x,%02x\n", entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
1991 trace( "palette %p\n", h
);
1992 h
= GetClipboardData( CF_METAFILEPICT
);
1993 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1994 ok( GetObjectType( ((METAFILEPICT
*)h
)->hMF
) == OBJ_METAFILE
,
1995 "wrong object %p\n", ((METAFILEPICT
*)h
)->hMF
);
1996 trace( "metafile %p\n", h
);
1997 h
= GetClipboardData( CF_DSPMETAFILEPICT
);
1998 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1999 ok( GetObjectType( ((METAFILEPICT
*)h
)->hMF
) == OBJ_METAFILE
,
2000 "wrong object %p\n", ((METAFILEPICT
*)h
)->hMF
);
2001 trace( "metafile2 %p\n", h
);
2002 h
= GetClipboardData( CF_ENHMETAFILE
);
2003 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2004 ok( GetEnhMetaFileBits( h
, sizeof(buffer
), buffer
) > sizeof(ENHMETAHEADER
),
2005 "GetEnhMetaFileBits failed on %p\n", h
);
2006 ok( ((ENHMETAHEADER
*)buffer
)->nRecords
== 3,
2007 "wrong records %u\n", ((ENHMETAHEADER
*)buffer
)->nRecords
);
2008 trace( "enhmetafile %p\n", h
);
2009 h
= GetClipboardData( CF_DSPENHMETAFILE
);
2010 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2011 ok( GetEnhMetaFileBits( h
, sizeof(buffer
), buffer
) > sizeof(ENHMETAHEADER
),
2012 "GetEnhMetaFileBits failed on %p\n", h
);
2013 ok( ((ENHMETAHEADER
*)buffer
)->nRecords
== 3,
2014 "wrong records %u\n", ((ENHMETAHEADER
*)buffer
)->nRecords
);
2015 trace( "enhmetafile2 %p\n", h
);
2016 h
= GetClipboardData( CF_DIB
);
2017 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2018 h
= GetClipboardData( CF_DIBV5
);
2019 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2020 r
= CloseClipboard();
2021 ok( r
, "gle %d\n", GetLastError() );
2024 static void test_handles_process_open( const char *str
)
2026 HANDLE h
, text
= GlobalAlloc( GMEM_DDESHARE
|GMEM_MOVEABLE
, strlen(str
) + 1 );
2027 char *ptr
= GlobalLock( text
);
2030 GlobalUnlock( text
);
2032 /* clipboard already open by parent process */
2033 h
= SetClipboardData( CF_TEXT
, text
);
2034 ok( h
== text
, "wrong mem %p / %p\n", h
, text
);
2035 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2038 static void test_handles_process_dib( const char *str
)
2043 r
= OpenClipboard( 0 );
2044 ok( r
, "gle %d\n", GetLastError() );
2045 h
= GetClipboardData( CF_BITMAP
);
2046 ok( !GetObjectType( h
), "expected invalid object %p\n", h
);
2047 trace( "dibsection %p\n", h
);
2048 r
= CloseClipboard();
2049 ok( r
, "gle %d\n", GetLastError() );
2052 static void test_data_handles(void)
2057 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
2061 ok( hwnd
!= 0, "window creation failed\n" );
2062 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
2064 test_handles( GetDesktopWindow() );
2065 test_handles( hwnd
);
2066 run_thread( test_handles_thread
, hwnd
, __LINE__
);
2068 bitmap
= CreateBitmap( 13, 17, 1, 1, NULL
);
2069 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
2070 palette
= CreatePalette( &logpalette
);
2072 r
= OpenClipboard( hwnd
);
2073 ok( r
, "gle %d\n", GetLastError() );
2074 r
= EmptyClipboard();
2075 ok( r
, "gle %d\n", GetLastError() );
2076 h
= SetClipboardData( CF_TEXT
, create_textA() );
2077 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2078 h
= SetClipboardData( format_id
, create_textA() );
2079 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2080 h
= SetClipboardData( CF_BITMAP
, bitmap
);
2081 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
2082 h
= SetClipboardData( CF_DSPBITMAP
, bitmap2
);
2083 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
2084 h
= SetClipboardData( CF_PALETTE
, palette
);
2085 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
2086 h
= SetClipboardData( CF_METAFILEPICT
, create_metafile() );
2087 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2088 trace( "metafile %p\n", h
);
2089 h
= SetClipboardData( CF_DSPMETAFILEPICT
, create_metafile() );
2090 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2091 trace( "metafile2 %p\n", h
);
2092 h
= SetClipboardData( CF_ENHMETAFILE
, create_emf() );
2093 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2094 trace( "enhmetafile %p\n", h
);
2095 h
= SetClipboardData( CF_DSPENHMETAFILE
, create_emf() );
2096 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2097 trace( "enhmetafile2 %p\n", h
);
2098 h
= SetClipboardData( CF_GDIOBJFIRST
+ 3, create_textA() );
2099 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2100 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, create_textA() );
2101 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2102 r
= CloseClipboard();
2103 ok( r
, "gle %d\n", GetLastError() );
2105 run_thread( test_handles_thread2
, 0, __LINE__
);
2106 run_process( "handles test" );
2108 r
= OpenClipboard( hwnd
);
2109 ok( r
, "gle %d\n", GetLastError() );
2110 h
= GetClipboardData( CF_TEXT
);
2111 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2112 h
= GetClipboardData( format_id
);
2113 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2114 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
2115 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2116 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
2117 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2119 r
= EmptyClipboard();
2120 ok( r
, "gle %d\n", GetLastError() );
2121 text
= create_textA();
2122 h
= SetClipboardData( CF_TEXT
, text
);
2123 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2125 run_process( "handles_open foobar" );
2127 ok( is_moveable( text
), "expected moveable mem %p\n", text
);
2128 h
= GetClipboardData( CF_TEXT
);
2129 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2130 ok( is_moveable( text
), "expected moveable mem %p\n", text
);
2131 ptr
= GlobalLock( h
);
2132 ok( !strcmp( ptr
, "foobar" ), "wrong data '%.8s'\n", ptr
);
2135 r
= EmptyClipboard();
2136 ok( r
, "gle %d\n", GetLastError() );
2137 ok( is_fixed( h
), "expected free mem %p\n", h
);
2138 ok( is_freed( text
) || broken( is_moveable(text
) ), /* w2003, w2008 */
2139 "expected free mem %p\n", text
);
2140 r
= CloseClipboard();
2141 ok( r
, "gle %d\n", GetLastError() );
2143 /* test CF_BITMAP with a DIB section */
2144 memset( &bmi
, 0, sizeof(bmi
) );
2145 bmi
.bmiHeader
.biSize
= sizeof( bmi
.bmiHeader
);
2146 bmi
.bmiHeader
.biWidth
= 29;
2147 bmi
.bmiHeader
.biHeight
= 13;
2148 bmi
.bmiHeader
.biPlanes
= 1;
2149 bmi
.bmiHeader
.biBitCount
= 32;
2150 bitmap
= CreateDIBSection( 0, &bmi
, DIB_RGB_COLORS
, &bits
, 0, 0 );
2152 r
= OpenClipboard( hwnd
);
2153 ok( r
, "gle %d\n", GetLastError() );
2154 r
= EmptyClipboard();
2155 ok( r
, "gle %d\n", GetLastError() );
2156 h
= SetClipboardData( CF_BITMAP
, bitmap
);
2157 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
2158 trace( "dibsection %p\n", h
);
2159 r
= CloseClipboard();
2160 ok( r
, "gle %d\n", GetLastError() );
2162 run_process( "handles_dib dummy" );
2164 r
= OpenClipboard( hwnd
);
2165 ok( r
, "gle %d\n", GetLastError() );
2166 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
2167 r
= EmptyClipboard();
2168 ok( r
, "gle %d\n", GetLastError() );
2169 ok( !GetObjectType( bitmap
), "expected deleted %p\n", bitmap
);
2170 r
= CloseClipboard();
2171 ok( r
, "gle %d\n", GetLastError() );
2173 DestroyWindow( hwnd
);
2176 static void test_GetUpdatedClipboardFormats(void)
2179 UINT count
, formats
[256];
2181 if (!pGetUpdatedClipboardFormats
)
2183 win_skip( "GetUpdatedClipboardFormats not supported\n" );
2188 r
= pGetUpdatedClipboardFormats( NULL
, 0, &count
);
2189 ok( r
, "gle %d\n", GetLastError() );
2190 ok( !count
, "wrong count %u\n", count
);
2193 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2194 ok( r
, "gle %d\n", GetLastError() );
2195 ok( !count
, "wrong count %u\n", count
);
2197 SetLastError( 0xdeadbeef );
2198 r
= pGetUpdatedClipboardFormats( formats
, 256, NULL
);
2199 ok( !r
, "succeeded\n" );
2200 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2203 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2204 ok( r
, "gle %d\n", GetLastError() );
2205 ok( !count
, "wrong count %u\n", count
);
2207 r
= OpenClipboard( 0 );
2208 ok( r
, "gle %d\n", GetLastError() );
2209 r
= EmptyClipboard();
2210 ok( r
, "gle %d\n", GetLastError() );
2213 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2214 ok( r
, "gle %d\n", GetLastError() );
2215 ok( !count
, "wrong count %u\n", count
);
2217 SetClipboardData( CF_UNICODETEXT
, 0 );
2220 memset( formats
, 0xcc, sizeof(formats
) );
2221 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2222 ok( r
, "gle %d\n", GetLastError() );
2223 ok( count
== 1, "wrong count %u\n", count
);
2224 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2225 ok( formats
[1] == 0xcccccccc, "wrong format %u\n", formats
[1] );
2227 SetClipboardData( CF_TEXT
, 0 );
2229 memset( formats
, 0xcc, sizeof(formats
) );
2230 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2231 ok( r
, "gle %d\n", GetLastError() );
2232 ok( count
== 2, "wrong count %u\n", count
);
2233 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2234 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
2235 ok( formats
[2] == 0xcccccccc, "wrong format %u\n", formats
[2] );
2237 SetLastError( 0xdeadbeef );
2239 r
= pGetUpdatedClipboardFormats( formats
, 0, &count
);
2240 ok( !r
, "succeeded\n" );
2241 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2242 ok( count
== 2, "wrong count %u\n", count
);
2244 SetLastError( 0xdeadbeef );
2246 r
= pGetUpdatedClipboardFormats( formats
, 1, &count
);
2247 ok( !r
, "succeeded\n" );
2248 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2249 ok( count
== 2, "wrong count %u\n", count
);
2251 r
= CloseClipboard();
2252 ok( r
, "gle %d\n", GetLastError() );
2255 memset( formats
, 0xcc, sizeof(formats
) );
2256 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2257 ok( r
, "gle %d\n", GetLastError() );
2258 ok( count
== 4, "wrong count %u\n", count
);
2259 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2260 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
2261 ok( formats
[2] == CF_LOCALE
, "wrong format %u\n", formats
[2] );
2262 ok( formats
[3] == CF_OEMTEXT
, "wrong format %u\n", formats
[3] );
2263 ok( formats
[4] == 0xcccccccc, "wrong format %u\n", formats
[4] );
2266 memset( formats
, 0xcc, sizeof(formats
) );
2267 r
= pGetUpdatedClipboardFormats( formats
, 2, &count
);
2268 ok( !r
, "gle %d\n", GetLastError() );
2269 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2270 ok( count
== 4, "wrong count %u\n", count
);
2271 ok( formats
[0] == 0xcccccccc, "wrong format %u\n", formats
[0] );
2274 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2275 ok( !r
, "gle %d\n", GetLastError() );
2276 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2277 ok( count
== 4, "wrong count %u\n", count
);
2280 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2281 ok( !r
, "gle %d\n", GetLastError() );
2282 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2283 ok( count
== 4, "wrong count %u\n", count
);
2293 { "foo", {}, 3 }, /* 0 */
2295 { "foo\0bar", {}, 7 },
2296 { "foo\0bar", {}, 8 },
2297 { "", {'f','o','o'}, 3 * sizeof(WCHAR
) },
2298 { "", {'f','o','o',0}, 4 * sizeof(WCHAR
) }, /* 5 */
2299 { "", {'f','o','o',0,'b','a','r'}, 7 * sizeof(WCHAR
) },
2300 { "", {'f','o','o',0,'b','a','r',0}, 8 * sizeof(WCHAR
) },
2301 { "", {'f','o','o'}, 1 },
2302 { "", {'f','o','o'}, 2 },
2303 { "", {'f','o','o'}, 5 }, /* 10 */
2304 { "", {'f','o','o',0}, 7 },
2305 { "", {'f','o','o',0}, 9 },
2308 static void test_string_data(void)
2317 for (i
= 0; i
< sizeof(test_data
) / sizeof(test_data
[0]); i
++)
2319 /* 1-byte Unicode strings crash on Win64 */
2321 if (!test_data
[i
].strA
[0] && test_data
[i
].len
< sizeof(WCHAR
)) continue;
2323 r
= OpenClipboard( 0 );
2324 ok( r
, "gle %d\n", GetLastError() );
2325 r
= EmptyClipboard();
2326 ok( r
, "gle %d\n", GetLastError() );
2327 data
= GlobalAlloc( GMEM_FIXED
, test_data
[i
].len
);
2328 if (test_data
[i
].strA
[0])
2330 memcpy( data
, test_data
[i
].strA
, test_data
[i
].len
);
2331 SetClipboardData( CF_TEXT
, data
);
2332 memcpy( bufferA
, test_data
[i
].strA
, test_data
[i
].len
);
2333 bufferA
[test_data
[i
].len
- 1] = 0;
2334 ok( !memcmp( data
, bufferA
, test_data
[i
].len
),
2335 "%u: wrong data %.*s\n", i
, test_data
[i
].len
, (char *)data
);
2339 memcpy( data
, test_data
[i
].strW
, test_data
[i
].len
);
2340 SetClipboardData( CF_UNICODETEXT
, data
);
2341 memcpy( bufferW
, test_data
[i
].strW
, test_data
[i
].len
);
2342 bufferW
[(test_data
[i
].len
+ 1) / sizeof(WCHAR
) - 1] = 0;
2343 ok( !memcmp( data
, bufferW
, test_data
[i
].len
),
2344 "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, (test_data
[i
].len
+ 1) / sizeof(WCHAR
) ));
2346 r
= CloseClipboard();
2347 ok( r
, "gle %d\n", GetLastError() );
2348 sprintf( cmd
, "string_data %u", i
);
2353 static void test_string_data_process( int i
)
2361 r
= OpenClipboard( 0 );
2362 ok( r
, "gle %d\n", GetLastError() );
2363 if (test_data
[i
].strA
[0])
2365 data
= GetClipboardData( CF_TEXT
);
2366 ok( data
!= 0, "%u: could not get data\n", i
);
2367 len
= GlobalSize( data
);
2368 ok( len
== test_data
[i
].len
, "%u: wrong size %u / %u\n", i
, len
, test_data
[i
].len
);
2369 memcpy( bufferA
, test_data
[i
].strA
, test_data
[i
].len
);
2370 bufferA
[test_data
[i
].len
- 1] = 0;
2371 ok( !memcmp( data
, bufferA
, len
), "%u: wrong data %.*s\n", i
, len
, (char *)data
);
2372 data
= GetClipboardData( CF_UNICODETEXT
);
2373 ok( data
!= 0, "%u: could not get data\n", i
);
2374 len
= GlobalSize( data
);
2375 len2
= MultiByteToWideChar( CP_ACP
, 0, bufferA
, test_data
[i
].len
, bufferW
, 12 );
2376 ok( len
== len2
* sizeof(WCHAR
), "%u: wrong size %u / %u\n", i
, len
, len2
);
2377 ok( !memcmp( data
, bufferW
, len
), "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, len2
));
2381 data
= GetClipboardData( CF_UNICODETEXT
);
2382 ok( data
!= 0, "%u: could not get data\n", i
);
2383 len
= GlobalSize( data
);
2384 ok( len
== test_data
[i
].len
, "%u: wrong size %u / %u\n", i
, len
, test_data
[i
].len
);
2385 memcpy( bufferW
, test_data
[i
].strW
, test_data
[i
].len
);
2386 bufferW
[(test_data
[i
].len
+ 1) / sizeof(WCHAR
) - 1] = 0;
2387 ok( !memcmp( data
, bufferW
, len
),
2388 "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, (len
+ 1) / sizeof(WCHAR
) ));
2389 data
= GetClipboardData( CF_TEXT
);
2390 if (test_data
[i
].len
>= sizeof(WCHAR
))
2392 ok( data
!= 0, "%u: could not get data\n", i
);
2393 len
= GlobalSize( data
);
2394 len2
= WideCharToMultiByte( CP_ACP
, 0, bufferW
, test_data
[i
].len
/ sizeof(WCHAR
),
2395 bufferA
, 12, NULL
, NULL
);
2396 bufferA
[len2
- 1] = 0;
2397 ok( len
== len2
, "%u: wrong size %u / %u\n", i
, len
, len2
);
2398 ok( !memcmp( data
, bufferA
, len
), "%u: wrong data %.*s\n", i
, len
, (char *)data
);
2402 ok( !data
, "%u: got data for empty string\n", i
);
2403 ok( IsClipboardFormatAvailable( CF_TEXT
), "%u: text not available\n", i
);
2406 r
= CloseClipboard();
2407 ok( r
, "gle %d\n", GetLastError() );
2410 START_TEST(clipboard
)
2413 int argc
= winetest_get_mainargs( &argv
);
2414 HMODULE mod
= GetModuleHandleA( "user32" );
2417 pAddClipboardFormatListener
= (void *)GetProcAddress( mod
, "AddClipboardFormatListener" );
2418 pRemoveClipboardFormatListener
= (void *)GetProcAddress( mod
, "RemoveClipboardFormatListener" );
2419 pGetClipboardSequenceNumber
= (void *)GetProcAddress( mod
, "GetClipboardSequenceNumber" );
2420 pGetUpdatedClipboardFormats
= (void *)GetProcAddress( mod
, "GetUpdatedClipboardFormats" );
2422 if (argc
== 4 && !strcmp( argv
[2], "set_clipboard_data" ))
2424 set_clipboard_data_process( atoi( argv
[3] ));
2427 if (argc
== 4 && !strcmp( argv
[2], "grab_clipboard" ))
2429 grab_clipboard_process( atoi( argv
[3] ));
2432 if (argc
== 4 && !strcmp( argv
[2], "handles" ))
2434 test_handles_process( argv
[3] );
2437 if (argc
== 4 && !strcmp( argv
[2], "handles_open" ))
2439 test_handles_process_open( argv
[3] );
2442 if (argc
== 4 && !strcmp( argv
[2], "handles_dib" ))
2444 test_handles_process_dib( argv
[3] );
2447 if (argc
== 4 && !strcmp( argv
[2], "string_data" ))
2449 test_string_data_process( atoi( argv
[3] ));
2453 test_RegisterClipboardFormatA();
2454 test_ClipboardOwner();
2457 test_data_handles();
2458 test_GetUpdatedClipboardFormats();