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 const BOOL is_win64
= sizeof(void *) > sizeof(int);
35 static int thread_from_line
;
38 static DWORD WINAPI
open_clipboard_thread(LPVOID arg
)
41 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
45 static DWORD WINAPI
empty_clipboard_thread(LPVOID arg
)
47 SetLastError( 0xdeadbeef );
48 ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line
);
49 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
50 thread_from_line
, GetLastError());
54 static DWORD WINAPI
open_and_empty_clipboard_thread(LPVOID arg
)
57 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
58 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
62 static DWORD WINAPI
open_and_empty_clipboard_win_thread(LPVOID arg
)
64 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
65 ok(OpenClipboard(hwnd
), "%u: OpenClipboard failed\n", thread_from_line
);
66 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
70 static DWORD WINAPI
set_clipboard_data_thread(LPVOID arg
)
75 SetLastError( 0xdeadbeef );
76 if (GetClipboardOwner() == hwnd
)
78 SetClipboardData( CF_WAVE
, 0 );
79 ok( IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData failed\n", thread_from_line
);
80 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
81 ok( ret
!= 0, "%u: SetClipboardData failed err %u\n", thread_from_line
, GetLastError() );
82 SetLastError( 0xdeadbeef );
83 ret
= GetClipboardData( CF_WAVE
);
84 ok( !ret
, "%u: GetClipboardData succeeded\n", thread_from_line
);
85 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
86 thread_from_line
, GetLastError());
90 SetClipboardData( CF_WAVE
, 0 );
91 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
92 thread_from_line
, GetLastError());
93 ok( !IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData succeeded\n", thread_from_line
);
94 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
95 ok( !ret
, "%u: SetClipboardData succeeded\n", thread_from_line
);
96 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
97 thread_from_line
, GetLastError());
102 static void set_clipboard_data_process( int arg
)
106 SetLastError( 0xdeadbeef );
109 todo_wine_if( arg
== 1 || arg
== 3 )
110 ok( IsClipboardFormatAvailable( CF_WAVE
), "process %u: CF_WAVE not available\n", arg
);
111 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
112 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
116 SetClipboardData( CF_WAVE
, 0 );
117 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
118 arg
, GetLastError());
119 ok( !IsClipboardFormatAvailable( CF_WAVE
), "process %u: SetClipboardData succeeded\n", arg
);
120 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
121 ok( !ret
, "process %u: SetClipboardData succeeded\n", arg
);
122 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
123 arg
, GetLastError());
127 static void grab_clipboard_process( int arg
)
131 SetLastError( 0xdeadbeef );
132 ret
= OpenClipboard( 0 );
133 ok( ret
, "OpenClipboard failed\n" );
134 ret
= EmptyClipboard();
135 ok( ret
, "EmptyClipboard failed\n" );
138 HANDLE ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
139 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
143 static void run_thread( LPTHREAD_START_ROUTINE func
, void *arg
, int line
)
148 thread_from_line
= line
;
149 thread
= CreateThread(NULL
, 0, func
, arg
, 0, NULL
);
150 ok(thread
!= NULL
, "%u: CreateThread failed with error %d\n", line
, GetLastError());
153 ret
= MsgWaitForMultipleObjectsEx( 1, &thread
, 1000, QS_ALLINPUT
, 0 );
154 if (ret
== WAIT_OBJECT_0
+ 1)
157 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
161 ok(ret
== WAIT_OBJECT_0
, "%u: expected WAIT_OBJECT_0, got %u\n", line
, ret
);
165 static void run_process( const char *args
)
168 PROCESS_INFORMATION info
;
169 STARTUPINFOA startup
;
171 sprintf( cmd
, "%s clipboard %s", argv0
, args
);
172 memset( &startup
, 0, sizeof(startup
) );
173 startup
.cb
= sizeof(startup
);
174 ok( CreateProcessA( NULL
, cmd
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &startup
, &info
),
175 "CreateProcess %s failed\n", cmd
);
177 winetest_wait_child_process( info
.hProcess
);
178 CloseHandle( info
.hProcess
);
179 CloseHandle( info
.hThread
);
182 static WNDPROC old_proc
;
183 static LRESULT CALLBACK
winproc_wrapper( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
185 static int wm_renderallformats
;
186 static int wm_drawclipboard
;
188 DWORD msg_flags
= InSendMessageEx( NULL
);
190 if (!seqno
) seqno
= GetClipboardSequenceNumber();
192 trace( "%p msg %04x\n", hwnd
, msg
);
193 if (!wm_renderallformats
)
195 ok( GetClipboardOwner() == hwnd
, "%04x: wrong owner %p/%p\n", msg
, GetClipboardOwner(), hwnd
);
196 ok( seqno
== GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg
);
200 ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg
, GetClipboardOwner() );
201 ok( seqno
+ 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg
);
203 ok( GetClipboardViewer() == hwnd
, "%04x: wrong viewer %p/%p\n", msg
, GetClipboardViewer(), hwnd
);
204 ok( GetOpenClipboardWindow() == hwnd
, "%04x: wrong open win %p/%p\n",
205 msg
, GetOpenClipboardWindow(), hwnd
);
210 ok( wm_renderallformats
, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
211 todo_wine
ok( wm_drawclipboard
, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
213 case WM_DRAWCLIPBOARD
:
214 ok( msg_flags
== ISMEX_NOSEND
, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
217 case WM_RENDERALLFORMATS
:
218 ok( msg_flags
== ISMEX_NOSEND
, "WM_RENDERALLFORMATS wrong flags %x\n", msg_flags
);
219 wm_renderallformats
++;
222 return old_proc( hwnd
, msg
, wp
, lp
);
225 static void test_ClipboardOwner(void)
230 SetLastError(0xdeadbeef);
231 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
232 "could not perform clipboard test: clipboard already owned\n");
234 hWnd1
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
235 0, 0, 10, 10, 0, 0, 0, NULL
);
236 ok(hWnd1
!= 0, "CreateWindowExA error %d\n", GetLastError());
237 trace("hWnd1 = %p\n", hWnd1
);
239 hWnd2
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
240 0, 0, 10, 10, 0, 0, 0, NULL
);
241 ok(hWnd2
!= 0, "CreateWindowExA error %d\n", GetLastError());
242 trace("hWnd2 = %p\n", hWnd2
);
244 SetLastError(0xdeadbeef);
245 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
246 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
247 "wrong error %u\n", GetLastError());
249 ok(OpenClipboard(0), "OpenClipboard failed\n");
250 ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
251 ok(!OpenClipboard(hWnd1
), "OpenClipboard should fail since clipboard already opened\n");
252 ok(OpenClipboard(0), "OpenClipboard again failed\n");
253 ret
= CloseClipboard();
254 ok( ret
, "CloseClipboard error %d\n", GetLastError());
256 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
257 run_thread( open_clipboard_thread
, hWnd1
, __LINE__
);
258 run_thread( empty_clipboard_thread
, 0, __LINE__
);
259 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
260 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
261 ok( !GetClipboardData( CF_WAVE
), "CF_WAVE data available\n" );
262 run_process( "set_clipboard_data 0" );
263 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
264 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
266 SetLastError(0xdeadbeef);
267 ret
= OpenClipboard(hWnd2
);
268 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
269 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
271 SetLastError(0xdeadbeef);
272 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
273 ret
= EmptyClipboard();
274 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
275 ok(GetClipboardOwner() == hWnd1
, "clipboard should be owned by %p, not by %p\n", hWnd1
, GetClipboardOwner());
276 run_thread( empty_clipboard_thread
, 0, __LINE__
);
277 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
278 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
279 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
280 run_process( "set_clipboard_data 1" );
282 SetLastError(0xdeadbeef);
283 ret
= OpenClipboard(hWnd2
);
284 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
285 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
287 ret
= CloseClipboard();
288 ok( ret
, "CloseClipboard error %d\n", GetLastError());
289 ok(GetClipboardOwner() == hWnd1
, "clipboard should still be owned\n");
291 /* any window will do, even from a different process */
292 ret
= OpenClipboard( GetDesktopWindow() );
293 ok( ret
, "OpenClipboard error %d\n", GetLastError());
294 ret
= EmptyClipboard();
295 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
296 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
297 GetClipboardOwner(), GetDesktopWindow() );
298 run_thread( set_clipboard_data_thread
, GetDesktopWindow(), __LINE__
);
299 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
300 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
301 run_process( "set_clipboard_data 2" );
302 ret
= CloseClipboard();
303 ok( ret
, "CloseClipboard error %d\n", GetLastError());
305 ret
= OpenClipboard( hWnd1
);
306 ok( ret
, "OpenClipboard error %d\n", GetLastError());
307 ret
= EmptyClipboard();
308 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
309 SetClipboardData( CF_WAVE
, 0 );
310 SetClipboardViewer( hWnd1
);
311 ok( GetClipboardOwner() == hWnd1
, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1
);
312 ok( GetClipboardViewer() == hWnd1
, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1
);
313 ok( GetOpenClipboardWindow() == hWnd1
, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1
);
314 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
316 old_proc
= (WNDPROC
)SetWindowLongPtrA( hWnd1
, GWLP_WNDPROC
, (LONG_PTR
)winproc_wrapper
);
317 ret
= DestroyWindow(hWnd1
);
318 ok( ret
, "DestroyWindow error %d\n", GetLastError());
319 ret
= DestroyWindow(hWnd2
);
320 ok( ret
, "DestroyWindow error %d\n", GetLastError());
321 SetLastError(0xdeadbeef);
322 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
323 ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n");
324 ok(!GetOpenClipboardWindow() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n");
325 todo_wine
ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
327 SetLastError( 0xdeadbeef );
328 ret
= CloseClipboard();
329 ok( !ret
, "CloseClipboard succeeded\n" );
330 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
332 ret
= OpenClipboard( 0 );
333 ok( ret
, "OpenClipboard error %d\n", GetLastError());
334 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
335 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
336 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
337 run_process( "set_clipboard_data 3" );
338 ret
= CloseClipboard();
339 ok( ret
, "CloseClipboard error %d\n", GetLastError());
341 run_thread( open_and_empty_clipboard_thread
, 0, __LINE__
);
342 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
343 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
345 ret
= OpenClipboard( 0 );
346 ok( ret
, "OpenClipboard error %d\n", GetLastError());
347 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
348 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
349 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
350 run_process( "set_clipboard_data 4" );
351 ret
= EmptyClipboard();
352 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
353 ret
= CloseClipboard();
354 ok( ret
, "CloseClipboard error %d\n", GetLastError());
356 SetLastError( 0xdeadbeef );
357 ok( !SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 )),
358 "SetClipboardData succeeded\n" );
359 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
360 ok( !IsClipboardFormatAvailable( CF_WAVE
), "SetClipboardData succeeded\n" );
362 run_thread( open_and_empty_clipboard_thread
, GetDesktopWindow(), __LINE__
);
363 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
364 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n",
365 GetClipboardOwner(), GetDesktopWindow() );
367 run_thread( open_and_empty_clipboard_win_thread
, 0, __LINE__
);
368 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
369 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
372 static void test_RegisterClipboardFormatA(void)
375 UINT format_id
, format_id2
;
381 format_id
= RegisterClipboardFormatA("my_cool_clipboard_format");
382 ok(format_id
> 0xc000 && format_id
< 0xffff, "invalid clipboard format id %04x\n", format_id
);
384 format_id2
= RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
385 ok(format_id2
== format_id
, "invalid clipboard format id %04x\n", format_id2
);
387 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
388 ok(len
== lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len
);
389 ok(!lstrcmpA(buf
, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf
);
391 lstrcpyA(buf
, "foo");
392 SetLastError(0xdeadbeef);
393 len
= GetAtomNameA((ATOM
)format_id
, buf
, 256);
394 ok(len
== 0, "GetAtomNameA should fail\n");
395 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
399 lstrcpyA(buf
, "foo");
400 SetLastError(0xdeadbeef);
401 len
= GlobalGetAtomNameA((ATOM
)format_id
, buf
, 256);
402 ok(len
== 0, "GlobalGetAtomNameA should fail\n");
403 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
406 SetLastError(0xdeadbeef);
407 atom_id
= FindAtomA("my_cool_clipboard_format");
408 ok(atom_id
== 0, "FindAtomA should fail\n");
409 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
413 /* this relies on the clipboard and global atom table being different */
414 SetLastError(0xdeadbeef);
415 atom_id
= GlobalFindAtomA("my_cool_clipboard_format");
416 ok(atom_id
== 0, "GlobalFindAtomA should fail\n");
417 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
420 for (format_id
= 0; format_id
< 0xffff; format_id
++)
422 SetLastError(0xdeadbeef);
423 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
425 if (format_id
< 0xc000)
426 ok(!len
, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len
, buf
);
427 else if (len
&& winetest_debug
> 1)
428 trace("%04x: %s\n", format_id
, len
? buf
: "");
431 ret
= OpenClipboard(0);
432 ok( ret
, "OpenClipboard error %d\n", GetLastError());
434 /* try some invalid/unregistered formats */
435 SetLastError( 0xdeadbeef );
436 handle
= SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
437 ok( !handle
, "SetClipboardData succeeded\n" );
438 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError());
439 handle
= SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
440 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
441 handle
= SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
442 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
443 handle
= SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
444 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
446 ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
447 ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
448 ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
449 ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
450 ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
451 ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
453 trace("# of formats available: %d\n", CountClipboardFormats());
456 while ((format_id
= EnumClipboardFormats(format_id
)))
458 ok(IsClipboardFormatAvailable(format_id
), "format %04x was listed as available\n", format_id
);
459 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
460 trace("%04x: %s\n", format_id
, len
? buf
: "");
463 ret
= EmptyClipboard();
464 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
465 ret
=CloseClipboard();
466 ok( ret
, "CloseClipboard error %d\n", GetLastError());
468 if (CountClipboardFormats())
470 SetLastError(0xdeadbeef);
471 ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
472 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
,
473 "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError());
476 SetLastError(0xdeadbeef);
477 ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
478 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
479 "Wrong error %u\n", GetLastError());
481 format_id
= RegisterClipboardFormatA("#1234");
482 ok(format_id
== 1234, "invalid clipboard format id %04x\n", format_id
);
485 static HGLOBAL
create_textA(void)
487 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, 5);
488 char *p
= GlobalLock(h
);
494 static HGLOBAL
create_textW(void)
496 static const WCHAR testW
[] = {'t','e','s','t',0};
497 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, 5 * sizeof(WCHAR
));
498 WCHAR
*p
= GlobalLock(h
);
504 static HANDLE
create_metafile(void)
506 const RECT rect
= {0, 0, 100, 100};
510 HDC hdc
= CreateMetaFileA( NULL
);
511 ExtTextOutA( hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
512 mf
= CloseMetaFile( hdc
);
513 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, sizeof(*pict
) );
514 pict
= GlobalLock( ret
);
516 pict
->xExt
= pict
->yExt
= 100;
522 static HENHMETAFILE
create_emf(void)
524 const RECT rect
= {0, 0, 100, 100};
525 HDC hdc
= CreateEnhMetaFileA(NULL
, NULL
, &rect
, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
526 ExtTextOutA(hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
527 return CloseEnhMetaFile(hdc
);
530 static HBITMAP
create_bitmap(void)
532 HDC hdc
= GetDC( 0 );
533 UINT bpp
= GetDeviceCaps( hdc
, BITSPIXEL
);
535 return CreateBitmap( 10, 10, 1, bpp
, NULL
);
538 static HBITMAP
create_dib( BOOL v5
)
541 BITMAPINFOHEADER
*hdr
;
543 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
| GMEM_ZEROINIT
,
544 sizeof(BITMAPV5HEADER
) + 256 * sizeof(RGBQUAD
) + 16 * 16 * 4 );
545 hdr
= GlobalLock( ret
);
546 hdr
->biSize
= v5
? sizeof(BITMAPV5HEADER
) : sizeof(*hdr
);
550 hdr
->biBitCount
= 32;
551 hdr
->biCompression
= BI_RGB
;
554 BITMAPV5HEADER
*hdr5
= (BITMAPV5HEADER
*)hdr
;
555 hdr5
->bV5RedMask
= 0x0000ff;
556 hdr5
->bV5GreenMask
= 0x00ff00;
557 hdr5
->bV5BlueMask
= 0xff0000;
558 hdr5
->bV5AlphaMask
= 0xff000000;
564 static LRESULT CALLBACK
renderer_winproc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
566 static UINT rendered
;
571 case WM_RENDERFORMAT
:
572 if (wp
< 32) rendered
|= (1 << wp
);
579 return DefWindowProcA( hwnd
, msg
, wp
, lp
);
582 static void test_synthesized(void)
584 static const struct test
590 /* 0 */ { CF_TEXT
, { CF_TEXT
, CF_LOCALE
, CF_OEMTEXT
, CF_UNICODETEXT
}},
591 { CF_OEMTEXT
, { CF_OEMTEXT
, CF_LOCALE
, CF_TEXT
, CF_UNICODETEXT
}},
592 { CF_UNICODETEXT
, { CF_UNICODETEXT
, CF_LOCALE
, CF_TEXT
, CF_OEMTEXT
}},
593 { CF_ENHMETAFILE
, { CF_ENHMETAFILE
, CF_METAFILEPICT
}},
594 { CF_METAFILEPICT
, { CF_METAFILEPICT
, CF_ENHMETAFILE
}},
595 /* 5 */ { CF_BITMAP
, { CF_BITMAP
, CF_DIB
, CF_DIBV5
}},
596 { CF_DIB
, { CF_DIB
, CF_BITMAP
, CF_DIBV5
}},
597 { CF_DIBV5
, { CF_DIBV5
, CF_BITMAP
, CF_DIB
}},
603 UINT cf
, i
, j
, count
, rendered
;
607 hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
608 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)renderer_winproc
);
610 htext
= create_textA();
613 r
= OpenClipboard(NULL
);
614 ok(r
, "gle %d\n", GetLastError());
615 r
= EmptyClipboard();
616 ok(r
, "gle %d\n", GetLastError());
617 h
= SetClipboardData(CF_TEXT
, htext
);
618 ok(h
== htext
, "got %p\n", h
);
619 h
= SetClipboardData(CF_ENHMETAFILE
, emf
);
620 ok(h
== emf
, "got %p\n", h
);
621 r
= CloseClipboard();
622 ok(r
, "gle %d\n", GetLastError());
624 count
= CountClipboardFormats();
625 ok( count
== 6, "count %u\n", count
);
626 r
= IsClipboardFormatAvailable( CF_TEXT
);
627 ok( r
, "CF_TEXT not available err %d\n", GetLastError());
628 r
= IsClipboardFormatAvailable( CF_LOCALE
);
629 ok( r
, "CF_LOCALE not available err %d\n", GetLastError());
630 r
= IsClipboardFormatAvailable( CF_OEMTEXT
);
631 ok( r
, "CF_OEMTEXT not available err %d\n", GetLastError());
632 r
= IsClipboardFormatAvailable( CF_UNICODETEXT
);
633 ok( r
, "CF_UNICODETEXT not available err %d\n", GetLastError());
634 r
= IsClipboardFormatAvailable( CF_ENHMETAFILE
);
635 ok( r
, "CF_ENHMETAFILE not available err %d\n", GetLastError());
636 r
= IsClipboardFormatAvailable( CF_METAFILEPICT
);
637 ok( r
, "CF_METAFILEPICT not available err %d\n", GetLastError());
639 r
= OpenClipboard(NULL
);
640 ok(r
, "gle %d\n", GetLastError());
641 cf
= EnumClipboardFormats(0);
642 ok(cf
== CF_TEXT
, "cf %08x\n", cf
);
643 data
= GetClipboardData(cf
);
644 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
646 cf
= EnumClipboardFormats(cf
);
647 ok(cf
== CF_ENHMETAFILE
, "cf %08x\n", cf
);
648 data
= GetClipboardData(cf
);
649 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
651 cf
= EnumClipboardFormats(cf
);
652 ok(cf
== CF_LOCALE
, "cf %08x\n", cf
);
653 data
= GetClipboardData(cf
);
654 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
656 cf
= EnumClipboardFormats(cf
);
657 ok(cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
658 data
= GetClipboardData(cf
);
659 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
661 cf
= EnumClipboardFormats(cf
);
662 ok(cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
664 cf
= EnumClipboardFormats(cf
);
665 ok(cf
== CF_METAFILEPICT
, "cf %08x\n", cf
);
666 data
= GetClipboardData(cf
);
667 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
669 cf
= EnumClipboardFormats(cf
);
670 ok(cf
== 0, "cf %08x\n", cf
);
672 r
= EmptyClipboard();
673 ok(r
, "gle %d\n", GetLastError());
675 SetClipboardData( CF_UNICODETEXT
, create_textW() );
676 SetClipboardData( CF_TEXT
, create_textA() );
677 SetClipboardData( CF_OEMTEXT
, create_textA() );
678 r
= CloseClipboard();
679 ok(r
, "gle %d\n", GetLastError());
681 r
= OpenClipboard( NULL
);
682 ok(r
, "gle %d\n", GetLastError());
683 SetLastError( 0xdeadbeef );
684 cf
= EnumClipboardFormats(0);
685 ok( cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
686 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
687 SetLastError( 0xdeadbeef );
688 cf
= EnumClipboardFormats(cf
);
689 ok( cf
== CF_TEXT
, "cf %08x\n", cf
);
690 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
691 SetLastError( 0xdeadbeef );
692 cf
= EnumClipboardFormats(cf
);
693 ok( cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
694 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
695 SetLastError( 0xdeadbeef );
696 cf
= EnumClipboardFormats(cf
);
697 ok( cf
== CF_LOCALE
, "cf %08x\n", cf
);
698 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
699 SetLastError( 0xdeadbeef );
700 cf
= EnumClipboardFormats( cf
);
701 ok( cf
== 0, "cf %08x\n", cf
);
702 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
703 SetLastError( 0xdeadbeef );
704 cf
= EnumClipboardFormats( 0xdead );
705 ok( cf
== 0, "cf %08x\n", cf
);
706 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
708 r
= EmptyClipboard();
709 ok(r
, "gle %d\n", GetLastError());
711 r
= CloseClipboard();
712 ok(r
, "gle %d\n", GetLastError());
714 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
716 r
= OpenClipboard(NULL
);
717 ok(r
, "%u: gle %d\n", i
, GetLastError());
718 r
= EmptyClipboard();
719 ok(r
, "%u: gle %d\n", i
, GetLastError());
721 switch (tests
[i
].format
)
725 SetClipboardData( tests
[i
].format
, create_textA() );
728 SetClipboardData( CF_UNICODETEXT
, create_textW() );
731 SetClipboardData( CF_ENHMETAFILE
, create_emf() );
733 case CF_METAFILEPICT
:
734 SetClipboardData( CF_METAFILEPICT
, create_metafile() );
737 SetClipboardData( CF_BITMAP
, create_bitmap() );
741 SetClipboardData( tests
[i
].format
, create_dib( tests
[i
].format
== CF_DIBV5
));
745 count
= CountClipboardFormats();
746 ok( count
== 1, "%u: count %u\n", i
, count
);
748 r
= CloseClipboard();
749 ok(r
, "%u: gle %d\n", i
, GetLastError());
751 count
= CountClipboardFormats();
752 for (j
= 0; tests
[i
].expected
[j
]; j
++)
754 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
755 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
757 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
759 r
= OpenClipboard( hwnd
);
760 ok(r
, "%u: gle %d\n", i
, GetLastError());
762 for (j
= 0; tests
[i
].expected
[j
]; j
++)
764 cf
= EnumClipboardFormats( cf
);
765 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
766 i
, j
, cf
, tests
[i
].expected
[j
] );
767 if (cf
!= tests
[i
].expected
[j
]) break;
768 data
= GetClipboardData( cf
);
770 broken( tests
[i
].format
== CF_DIBV5
&& cf
== CF_DIB
), /* >= Vista */
771 "%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
);
782 if (!tests
[i
].expected
[j
])
784 cf
= EnumClipboardFormats( cf
);
785 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
788 /* now with delayed rendering */
790 r
= EmptyClipboard();
791 ok(r
, "%u: gle %d\n", i
, GetLastError());
793 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
794 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
796 SetClipboardData( tests
[i
].format
, 0 );
797 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
798 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
800 count
= CountClipboardFormats();
801 ok( count
== 1, "%u: count %u\n", i
, count
);
803 r
= CloseClipboard();
804 ok(r
, "%u: gle %d\n", i
, GetLastError());
805 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
806 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
808 count
= CountClipboardFormats();
809 for (j
= 0; tests
[i
].expected
[j
]; j
++)
811 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
812 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
814 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
815 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
816 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
818 r
= OpenClipboard(NULL
);
819 ok(r
, "%u: gle %d\n", i
, GetLastError());
821 for (j
= 0; tests
[i
].expected
[j
]; j
++)
823 cf
= EnumClipboardFormats( cf
);
824 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
825 i
, j
, cf
, tests
[i
].expected
[j
] );
826 if (cf
!= tests
[i
].expected
[j
]) break;
827 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
828 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
829 data
= GetClipboardData( cf
);
830 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
833 ok(data
!= NULL
, "%u: CF_LOCALE no data\n", i
);
834 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
838 ok(!data
, "%u: format %04x got data %p\n", i
, cf
, data
);
839 ok( rendered
== (1 << tests
[i
].format
),
840 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
841 /* try to render a second time */
842 data
= GetClipboardData( cf
);
843 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
844 ok( rendered
== (1 << tests
[i
].format
),
845 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
848 if (!tests
[i
].expected
[j
])
850 cf
= EnumClipboardFormats( cf
);
851 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
853 r
= CloseClipboard();
854 ok(r
, "%u: gle %d\n", i
, GetLastError());
855 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
856 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
859 r
= OpenClipboard(NULL
);
860 ok(r
, "gle %d\n", GetLastError());
861 r
= EmptyClipboard();
862 ok(r
, "gle %d\n", GetLastError());
863 r
= CloseClipboard();
864 ok(r
, "gle %d\n", GetLastError());
865 DestroyWindow( hwnd
);
868 static CRITICAL_SECTION clipboard_cs
;
869 static HWND next_wnd
;
870 static UINT wm_drawclipboard
;
871 static UINT wm_clipboardupdate
;
872 static UINT wm_destroyclipboard
;
873 static UINT wm_renderformat
;
874 static UINT nb_formats
;
875 static BOOL cross_thread
;
877 static LRESULT CALLBACK
clipboard_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
880 DWORD msg_flags
= InSendMessageEx( NULL
);
883 case WM_DRAWCLIPBOARD
:
884 ok( msg_flags
== (cross_thread
? ISMEX_NOTIFY
: ISMEX_NOSEND
),
885 "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
886 EnterCriticalSection(&clipboard_cs
);
888 LeaveCriticalSection(&clipboard_cs
);
890 case WM_CHANGECBCHAIN
:
891 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
892 "WM_CHANGECBCHAIN wrong flags %x\n", msg_flags
);
893 if (next_wnd
== (HWND
)wp
)
896 SendMessageA(next_wnd
, msg
, wp
, lp
);
898 case WM_DESTROYCLIPBOARD
:
899 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
900 "WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags
);
901 wm_destroyclipboard
++;
902 ok( GetClipboardOwner() == hwnd
, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
903 nb_formats
= CountClipboardFormats();
905 case WM_RENDERFORMAT
:
906 ok( !wm_renderformat
, "multiple WM_RENDERFORMAT %04x / %04lx\n", wm_renderformat
, wp
);
907 wm_renderformat
= wp
;
909 case WM_CLIPBOARDUPDATE
:
910 ok( msg_flags
== ISMEX_NOSEND
, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags
);
911 EnterCriticalSection(&clipboard_cs
);
912 wm_clipboardupdate
++;
913 LeaveCriticalSection(&clipboard_cs
);
916 ChangeClipboardChain(hwnd
, next_wnd
);
920 ret
= wm_drawclipboard
;
921 wm_drawclipboard
= 0;
924 ret
= wm_clipboardupdate
;
925 wm_clipboardupdate
= 0;
928 ret
= wm_destroyclipboard
;
929 wm_destroyclipboard
= 0;
932 ret
= wm_renderformat
;
939 return DefWindowProcA(hwnd
, msg
, wp
, lp
);
942 static DWORD WINAPI
clipboard_thread(void *param
)
944 HWND ret
, win
= param
;
948 UINT count
, fmt
, formats
, old_seq
= 0, seq
;
950 cross_thread
= (GetWindowThreadProcessId( win
, NULL
) != GetCurrentThreadId());
951 trace( "%s-threaded test\n", cross_thread
? "multi" : "single" );
953 if (pGetClipboardSequenceNumber
) old_seq
= pGetClipboardSequenceNumber();
955 EnterCriticalSection(&clipboard_cs
);
956 SetLastError(0xdeadbeef);
957 next_wnd
= SetClipboardViewer(win
);
958 ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
959 LeaveCriticalSection(&clipboard_cs
);
961 SetLastError( 0xdeadbeef );
962 ret
= SetClipboardViewer( (HWND
)0xdead );
963 ok( !ret
, "SetClipboardViewer succeeded\n" );
964 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
965 SetLastError( 0xdeadbeef );
966 r
= ChangeClipboardChain( win
, (HWND
)0xdead );
967 ok( !r
, "ChangeClipboardChain succeeded\n" );
968 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
969 SetLastError( 0xdeadbeef );
970 r
= ChangeClipboardChain( (HWND
)0xdead, next_wnd
);
971 ok( !r
, "ChangeClipboardChain succeeded\n" );
972 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
974 if (pAddClipboardFormatListener
)
976 r
= pAddClipboardFormatListener(win
);
977 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
978 SetLastError( 0xdeadbeef );
979 r
= pAddClipboardFormatListener( win
);
980 ok( !r
, "AddClipboardFormatListener succeeded\n" );
981 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
982 SetLastError( 0xdeadbeef );
983 r
= pAddClipboardFormatListener( (HWND
)0xdead );
984 ok( !r
, "AddClipboardFormatListener succeeded\n" );
985 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
986 r
= pAddClipboardFormatListener( GetDesktopWindow() );
987 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
988 r
= pRemoveClipboardFormatListener( GetDesktopWindow() );
989 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
992 if (pGetClipboardSequenceNumber
)
994 seq
= pGetClipboardSequenceNumber();
995 ok( seq
== old_seq
, "sequence changed\n" );
999 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1000 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1001 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1002 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1004 count
= SendMessageA( win
, WM_USER
+ 1, 0, 0 );
1005 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1006 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1007 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1008 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1009 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1011 SetLastError( 0xdeadbeef );
1012 r
= OpenClipboard( (HWND
)0xdead );
1013 ok( !r
, "OpenClipboard succeeded\n" );
1014 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1016 r
= OpenClipboard(win
);
1017 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1019 if (pGetClipboardSequenceNumber
)
1021 seq
= pGetClipboardSequenceNumber();
1022 ok( seq
== old_seq
, "sequence changed\n" );
1026 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1027 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1028 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1029 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1031 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1032 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1033 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1034 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1035 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1036 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1038 r
= EmptyClipboard();
1039 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1041 if (pGetClipboardSequenceNumber
)
1043 seq
= pGetClipboardSequenceNumber();
1044 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1049 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1050 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1051 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1052 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1054 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1055 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1056 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1057 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1058 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1059 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1060 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1061 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1063 r
= EmptyClipboard();
1064 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1065 /* sequence changes again, even though it was already empty */
1066 if (pGetClipboardSequenceNumber
)
1068 seq
= pGetClipboardSequenceNumber();
1069 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1074 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1075 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1076 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1077 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1079 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1080 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1081 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1082 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1083 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1084 ok( count
, "WM_DESTROYCLIPBOARD not received\n" );
1085 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1086 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1087 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1088 ok( !count
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1090 handle
= SetClipboardData( CF_TEXT
, create_textA() );
1091 ok(handle
!= 0, "SetClipboardData failed: %d\n", GetLastError());
1093 if (pGetClipboardSequenceNumber
)
1095 seq
= pGetClipboardSequenceNumber();
1096 todo_wine
ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1101 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1102 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1103 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1104 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1106 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1107 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1108 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1109 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1110 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1111 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1113 SetClipboardData( CF_UNICODETEXT
, 0 );
1115 if (pGetClipboardSequenceNumber
)
1117 seq
= pGetClipboardSequenceNumber();
1118 todo_wine
ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1123 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1124 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1125 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1126 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1128 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1129 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1130 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1131 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1132 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1133 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1135 SetClipboardData( CF_UNICODETEXT
, 0 ); /* same data again */
1137 if (pGetClipboardSequenceNumber
)
1139 seq
= pGetClipboardSequenceNumber();
1140 todo_wine
ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1145 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1146 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1147 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1148 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1150 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1151 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1152 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1153 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1154 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1155 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1157 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1158 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1159 ok( !IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1161 EnterCriticalSection(&clipboard_cs
);
1162 r
= CloseClipboard();
1163 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1164 LeaveCriticalSection(&clipboard_cs
);
1166 if (pGetClipboardSequenceNumber
)
1168 seq
= pGetClipboardSequenceNumber();
1169 todo_wine
ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1174 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1175 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1176 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1177 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1179 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1180 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1181 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1182 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1183 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1184 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1186 r
= OpenClipboard(win
);
1187 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1189 if (pGetClipboardSequenceNumber
)
1191 seq
= pGetClipboardSequenceNumber();
1192 ok( seq
== old_seq
, "sequence changed\n" );
1196 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1197 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1198 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1200 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1201 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1202 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1203 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1204 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1205 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1207 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1208 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1209 ok( IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1211 ok( GetClipboardOwner() == win
, "wrong owner %p\n", GetClipboardOwner());
1212 handle
= GetClipboardData( CF_UNICODETEXT
);
1213 ok( !handle
, "got data for CF_UNICODETEXT\n" );
1214 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1215 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1217 handle
= GetClipboardData( CF_OEMTEXT
);
1218 ok( !handle
, "got data for CF_OEMTEXT\n" );
1219 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1220 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1222 SetClipboardData( CF_WAVE
, 0 );
1223 if (pGetClipboardSequenceNumber
)
1225 seq
= pGetClipboardSequenceNumber();
1226 todo_wine
ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1231 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1232 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1233 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1234 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1236 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1237 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1238 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1239 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1240 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1241 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1243 r
= CloseClipboard();
1244 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1245 if (pGetClipboardSequenceNumber
)
1247 /* no synthesized format, so CloseClipboard doesn't change the sequence */
1248 seq
= pGetClipboardSequenceNumber();
1249 todo_wine
ok( seq
== old_seq
, "sequence changed\n" );
1254 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1255 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1256 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1257 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1259 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1260 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1261 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1262 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1263 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1264 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1266 r
= OpenClipboard(win
);
1267 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1268 r
= CloseClipboard();
1269 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1270 /* nothing changed */
1271 if (pGetClipboardSequenceNumber
)
1273 seq
= pGetClipboardSequenceNumber();
1274 ok( seq
== old_seq
, "sequence changed\n" );
1278 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1279 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1280 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1281 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1283 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1284 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1285 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1286 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1287 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1288 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1289 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1290 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1292 formats
= CountClipboardFormats();
1293 r
= OpenClipboard(0);
1294 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1295 r
= EmptyClipboard();
1296 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1297 r
= CloseClipboard();
1298 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1302 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1303 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1304 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1305 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1307 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1308 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1309 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1310 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1311 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1312 ok( count
== 1, "WM_DESTROYCLIPBOARD not received\n" );
1313 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1314 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1315 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1316 ok( count
== formats
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1318 r
= OpenClipboard(win
);
1319 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1320 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1321 if (pGetClipboardSequenceNumber
)
1323 seq
= pGetClipboardSequenceNumber();
1324 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1329 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1330 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1331 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1332 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1334 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1335 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1336 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1337 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1338 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1339 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1340 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1341 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1343 EnterCriticalSection(&clipboard_cs
);
1344 r
= CloseClipboard();
1345 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1346 LeaveCriticalSection(&clipboard_cs
);
1348 if (pGetClipboardSequenceNumber
)
1350 seq
= pGetClipboardSequenceNumber();
1351 todo_wine
ok( seq
== old_seq
, "sequence changed\n" );
1356 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1357 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1358 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1359 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1361 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1362 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1363 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1364 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1365 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1366 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1368 run_process( "grab_clipboard 0" );
1370 if (pGetClipboardSequenceNumber
)
1372 seq
= pGetClipboardSequenceNumber();
1373 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1378 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1379 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1380 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1381 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1382 cross_thread
= TRUE
;
1383 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1384 cross_thread
= FALSE
;
1386 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1387 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1388 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1389 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1390 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1391 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1393 r
= OpenClipboard(0);
1394 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1395 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1396 if (pGetClipboardSequenceNumber
)
1398 seq
= pGetClipboardSequenceNumber();
1399 todo_wine
ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1404 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1405 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1406 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1407 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1409 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1410 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1411 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1412 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1413 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1414 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1416 EnterCriticalSection(&clipboard_cs
);
1417 r
= CloseClipboard();
1418 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1419 LeaveCriticalSection(&clipboard_cs
);
1421 if (pGetClipboardSequenceNumber
)
1423 seq
= pGetClipboardSequenceNumber();
1424 todo_wine
ok( seq
== old_seq
, "sequence changed\n" );
1429 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD received\n" );
1430 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1431 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1432 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1434 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1435 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1436 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1437 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1438 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1439 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1441 run_process( "grab_clipboard 1" );
1443 if (pGetClipboardSequenceNumber
)
1445 seq
= pGetClipboardSequenceNumber();
1446 todo_wine_if (!cross_thread
)
1447 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1452 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1453 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1454 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1455 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1456 cross_thread
= TRUE
;
1457 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1458 cross_thread
= FALSE
;
1460 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1461 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1462 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1463 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1464 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1465 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1467 r
= OpenClipboard(0);
1468 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1469 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1470 if (pGetClipboardSequenceNumber
)
1472 seq
= pGetClipboardSequenceNumber();
1473 todo_wine
ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1478 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1479 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1480 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1481 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1483 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1484 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1485 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1486 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1487 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1488 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1490 EnterCriticalSection(&clipboard_cs
);
1491 r
= CloseClipboard();
1492 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1493 LeaveCriticalSection(&clipboard_cs
);
1495 if (pGetClipboardSequenceNumber
)
1497 seq
= pGetClipboardSequenceNumber();
1498 todo_wine
ok( seq
== old_seq
, "sequence changed\n" );
1503 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1504 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1505 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1506 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1508 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1509 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1510 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1511 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1512 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1513 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1515 r
= PostMessageA(win
, WM_USER
, 0, 0);
1516 ok(r
, "PostMessage failed: %d\n", GetLastError());
1518 if (pRemoveClipboardFormatListener
)
1520 r
= pRemoveClipboardFormatListener(win
);
1521 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1522 SetLastError( 0xdeadbeef );
1523 r
= pRemoveClipboardFormatListener(win
);
1524 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1525 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1526 SetLastError( 0xdeadbeef );
1527 r
= pRemoveClipboardFormatListener( (HWND
)0xdead );
1528 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1529 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1534 static void test_messages(void)
1542 InitializeCriticalSection(&clipboard_cs
);
1544 memset(&cls
, 0, sizeof(cls
));
1545 cls
.lpfnWndProc
= clipboard_wnd_proc
;
1546 cls
.hInstance
= GetModuleHandleA(NULL
);
1547 cls
.lpszClassName
= "clipboard_test";
1548 RegisterClassA(&cls
);
1550 win
= CreateWindowA("clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0);
1551 ok(win
!= NULL
, "CreateWindow failed: %d\n", GetLastError());
1553 thread
= CreateThread(NULL
, 0, clipboard_thread
, (void*)win
, 0, &tid
);
1554 ok(thread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1556 while(GetMessageA(&msg
, NULL
, 0, 0))
1558 ok( msg
.message
!= WM_DRAWCLIPBOARD
, "WM_DRAWCLIPBOARD was posted\n" );
1559 TranslateMessage(&msg
);
1560 DispatchMessageA(&msg
);
1563 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
1564 CloseHandle(thread
);
1566 DestroyWindow( win
);
1568 /* same tests again but inside a single thread */
1570 win
= CreateWindowA( "clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0 );
1571 ok( win
!= NULL
, "CreateWindow failed: %d\n", GetLastError() );
1573 clipboard_thread( win
);
1574 DestroyWindow( win
);
1576 UnregisterClassA("clipboard_test", GetModuleHandleA(NULL
));
1577 DeleteCriticalSection(&clipboard_cs
);
1580 static BOOL
is_moveable( HANDLE handle
)
1582 void *ptr
= GlobalLock( handle
);
1583 if (ptr
) GlobalUnlock( handle
);
1584 return ptr
&& ptr
!= handle
;
1587 static BOOL
is_fixed( HANDLE handle
)
1589 void *ptr
= GlobalLock( handle
);
1590 if (ptr
) GlobalUnlock( handle
);
1591 return ptr
&& ptr
== handle
;
1594 static BOOL
is_freed( HANDLE handle
)
1596 void *ptr
= GlobalLock( handle
);
1597 if (ptr
) GlobalUnlock( handle
);
1601 static UINT format_id
;
1602 static HBITMAP bitmap
, bitmap2
;
1603 static HPALETTE palette
;
1605 static const LOGPALETTE logpalette
= { 0x300, 1 };
1607 static void test_handles( HWND hwnd
)
1609 HGLOBAL h
, htext
, htext2
;
1613 BOOL is_owner
= (GetWindowThreadProcessId( hwnd
, &process
) && process
== GetCurrentProcessId());
1615 trace( "hwnd %p\n", hwnd
);
1616 htext
= create_textA();
1617 htext2
= create_textA();
1618 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
1619 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
1620 palette
= CreatePalette( &logpalette
);
1621 pen
= CreatePen( PS_SOLID
, 1, 0 );
1623 r
= OpenClipboard( hwnd
);
1624 ok( r
, "gle %d\n", GetLastError() );
1625 r
= EmptyClipboard();
1626 ok( r
, "gle %d\n", GetLastError() );
1628 h
= SetClipboardData( CF_TEXT
, htext
);
1629 ok( h
== htext
, "got %p\n", h
);
1630 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1631 h
= SetClipboardData( format_id
, htext2
);
1632 ok( h
== htext2
, "got %p\n", h
);
1633 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1634 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1635 ok( h
== bitmap
, "got %p\n", h
);
1636 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1637 h
= SetClipboardData( CF_PALETTE
, palette
);
1638 ok( h
== palette
, "got %p\n", h
);
1639 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1640 /* setting custom GDI formats crashes on 64-bit Windows */
1643 h
= SetClipboardData( CF_GDIOBJFIRST
+ 1, bitmap2
);
1644 ok( h
== bitmap2
, "got %p\n", h
);
1645 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1646 h
= SetClipboardData( CF_GDIOBJFIRST
+ 2, pen
);
1647 ok( h
== pen
, "got %p\n", h
);
1648 ok( GetObjectType( h
) == OBJ_PEN
, "expected pen %p\n", h
);
1651 data
= GetClipboardData( CF_TEXT
);
1652 ok( data
== htext
, "wrong data %p\n", data
);
1653 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1655 data
= GetClipboardData( format_id
);
1656 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1657 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1659 r
= CloseClipboard();
1660 ok( r
, "gle %d\n", GetLastError() );
1662 /* data handles are still valid */
1663 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1664 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext
);
1665 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1666 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1667 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1668 ok( GetObjectType( pen
) == OBJ_PEN
, "expected pen %p\n", pen
);
1670 r
= OpenClipboard( hwnd
);
1671 ok( r
, "gle %d\n", GetLastError() );
1673 /* and now they are freed, unless we are the owner */
1676 todo_wine
ok( is_freed( htext
), "expected freed mem %p\n", htext
);
1677 todo_wine
ok( is_freed( htext2
), "expected freed mem %p\n", htext
);
1679 data
= GetClipboardData( CF_TEXT
);
1680 todo_wine
ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1682 data
= GetClipboardData( format_id
);
1683 todo_wine
ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1687 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1688 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext
);
1690 data
= GetClipboardData( CF_TEXT
);
1691 ok( data
== htext
, "wrong data %p\n", data
);
1693 data
= GetClipboardData( format_id
);
1694 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1697 data
= GetClipboardData( CF_OEMTEXT
);
1698 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1699 data
= GetClipboardData( CF_UNICODETEXT
);
1700 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1701 data
= GetClipboardData( CF_LOCALE
);
1702 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1703 data
= GetClipboardData( CF_BITMAP
);
1704 ok( data
== bitmap
, "expected bitmap %p\n", data
);
1705 data
= GetClipboardData( CF_PALETTE
);
1706 ok( data
== palette
, "expected palette %p\n", data
);
1709 data
= GetClipboardData( CF_GDIOBJFIRST
+ 1 );
1710 ok( data
== bitmap2
, "expected bitmap2 %p\n", data
);
1711 data
= GetClipboardData( CF_GDIOBJFIRST
+ 2 );
1712 ok( data
== pen
, "expected pen %p\n", data
);
1714 data
= GetClipboardData( CF_DIB
);
1715 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1716 data
= GetClipboardData( CF_DIBV5
);
1717 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1719 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1720 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1721 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1722 ok( GetObjectType( pen
) == OBJ_PEN
, "expected pen %p\n", pen
);
1724 r
= EmptyClipboard();
1725 ok( r
, "gle %d\n", GetLastError() );
1727 /* w2003, w2008 don't seem to free the data here */
1728 ok( is_freed( htext
) || broken( !is_freed( htext
)), "expected freed mem %p\n", htext
);
1729 ok( is_freed( htext2
) || broken( !is_freed( htext2
)), "expected freed mem %p\n", htext
);
1730 ok( !GetObjectType( bitmap
), "expected freed handle %p\n", bitmap
);
1731 ok( !GetObjectType( palette
), "expected freed handle %p\n", palette
);
1732 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap2 %p\n", bitmap2
);
1733 ok( GetObjectType( pen
) == OBJ_PEN
, "expected pen %p\n", pen
);
1735 r
= CloseClipboard();
1736 ok( r
, "gle %d\n", GetLastError() );
1739 static DWORD WINAPI
test_handles_thread( void *arg
)
1741 trace( "running from different thread\n" );
1742 test_handles( (HWND
)arg
);
1746 static DWORD WINAPI
test_handles_thread2( void *arg
)
1752 r
= OpenClipboard( 0 );
1753 ok( r
, "gle %d\n", GetLastError() );
1754 h
= GetClipboardData( CF_TEXT
);
1755 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1756 ptr
= GlobalLock( h
);
1757 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1759 h
= GetClipboardData( format_id
);
1760 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1761 ptr
= GlobalLock( h
);
1762 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1764 h
= GetClipboardData( CF_BITMAP
);
1765 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1766 ok( h
== bitmap
, "different bitmap %p / %p\n", h
, bitmap
);
1767 trace( "bitmap %p\n", h
);
1768 h
= GetClipboardData( CF_PALETTE
);
1769 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1770 ok( h
== palette
, "different palette %p / %p\n", h
, palette
);
1771 trace( "palette %p\n", h
);
1774 h
= GetClipboardData( CF_GDIOBJFIRST
+ 1 );
1775 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1776 ok( h
== bitmap2
, "different bitmap %p / %p\n", h
, bitmap2
);
1777 trace( "bitmap2 %p\n", h
);
1778 h
= GetClipboardData( CF_GDIOBJFIRST
+ 2 );
1779 ok( GetObjectType( h
) == OBJ_PEN
, "expected pen %p\n", h
);
1780 ok( h
== pen
, "different pen %p / %p\n", h
, pen
);
1781 trace( "pen %p\n", h
);
1783 h
= GetClipboardData( CF_DIB
);
1784 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1785 h
= GetClipboardData( CF_DIBV5
);
1786 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1787 r
= CloseClipboard();
1788 ok( r
, "gle %d\n", GetLastError() );
1792 static void test_handles_process( const char *str
)
1798 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
1799 r
= OpenClipboard( 0 );
1800 ok( r
, "gle %d\n", GetLastError() );
1801 h
= GetClipboardData( CF_TEXT
);
1802 todo_wine_if( !h
) ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1803 ptr
= GlobalLock( h
);
1804 if (ptr
) todo_wine
ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1806 h
= GetClipboardData( format_id
);
1807 todo_wine
ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1808 ptr
= GlobalLock( h
);
1809 if (ptr
) ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1811 h
= GetClipboardData( CF_BITMAP
);
1812 todo_wine
ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1813 trace( "bitmap %p\n", h
);
1814 h
= GetClipboardData( CF_PALETTE
);
1815 todo_wine
ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1816 trace( "palette %p\n", h
);
1817 h
= GetClipboardData( CF_GDIOBJFIRST
+ 1 );
1818 ok( !GetObjectType( h
), "expected invalid %p\n", h
);
1819 trace( "bitmap2 %p\n", h
);
1820 h
= GetClipboardData( CF_GDIOBJFIRST
+ 2 );
1821 ok( !GetObjectType( h
), "expected invalid %p\n", h
);
1822 trace( "pen %p\n", h
);
1823 h
= GetClipboardData( CF_DIB
);
1824 todo_wine
ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1825 h
= GetClipboardData( CF_DIBV5
);
1826 todo_wine
ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1827 r
= CloseClipboard();
1828 ok( r
, "gle %d\n", GetLastError() );
1831 static void test_data_handles(void)
1835 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
1837 ok( hwnd
!= 0, "window creation failed\n" );
1838 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
1840 test_handles( GetDesktopWindow() );
1841 test_handles( hwnd
);
1842 run_thread( test_handles_thread
, hwnd
, __LINE__
);
1844 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
1845 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
1846 palette
= CreatePalette( &logpalette
);
1847 pen
= CreatePen( PS_SOLID
, 1, 0 );
1849 r
= OpenClipboard( hwnd
);
1850 ok( r
, "gle %d\n", GetLastError() );
1851 r
= EmptyClipboard();
1852 ok( r
, "gle %d\n", GetLastError() );
1853 h
= SetClipboardData( CF_TEXT
, create_textA() );
1854 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1855 h
= SetClipboardData( format_id
, create_textA() );
1856 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1857 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1858 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1859 h
= SetClipboardData( CF_PALETTE
, palette
);
1860 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1863 h
= SetClipboardData( CF_GDIOBJFIRST
+ 1, bitmap2
);
1864 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1865 h
= SetClipboardData( CF_GDIOBJFIRST
+ 2, pen
);
1866 ok( GetObjectType( h
) == OBJ_PEN
, "expected pen %p\n", h
);
1868 r
= CloseClipboard();
1869 ok( r
, "gle %d\n", GetLastError() );
1871 run_thread( test_handles_thread2
, 0, __LINE__
);
1872 run_process( "handles test" );
1874 r
= OpenClipboard( hwnd
);
1875 ok( r
, "gle %d\n", GetLastError() );
1876 h
= GetClipboardData( CF_TEXT
);
1877 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1878 h
= GetClipboardData( format_id
);
1879 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1880 r
= EmptyClipboard();
1881 ok( r
, "gle %d\n", GetLastError() );
1882 r
= CloseClipboard();
1883 ok( r
, "gle %d\n", GetLastError() );
1885 DestroyWindow( hwnd
);
1888 static void test_GetUpdatedClipboardFormats(void)
1891 UINT count
, formats
[256];
1893 if (!pGetUpdatedClipboardFormats
)
1895 win_skip( "GetUpdatedClipboardFormats not supported\n" );
1900 r
= pGetUpdatedClipboardFormats( NULL
, 0, &count
);
1901 ok( r
, "gle %d\n", GetLastError() );
1902 ok( !count
, "wrong count %u\n", count
);
1905 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
1906 ok( r
, "gle %d\n", GetLastError() );
1907 ok( !count
, "wrong count %u\n", count
);
1909 SetLastError( 0xdeadbeef );
1910 r
= pGetUpdatedClipboardFormats( formats
, 256, NULL
);
1911 ok( !r
, "succeeded\n" );
1912 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1915 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1916 ok( r
, "gle %d\n", GetLastError() );
1917 ok( !count
, "wrong count %u\n", count
);
1919 r
= OpenClipboard( 0 );
1920 ok( r
, "gle %d\n", GetLastError() );
1921 r
= EmptyClipboard();
1922 ok( r
, "gle %d\n", GetLastError() );
1925 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1926 ok( r
, "gle %d\n", GetLastError() );
1927 ok( !count
, "wrong count %u\n", count
);
1929 SetClipboardData( CF_UNICODETEXT
, 0 );
1932 memset( formats
, 0xcc, sizeof(formats
) );
1933 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1934 ok( r
, "gle %d\n", GetLastError() );
1935 ok( count
== 1, "wrong count %u\n", count
);
1936 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
1937 ok( formats
[1] == 0xcccccccc, "wrong format %u\n", formats
[1] );
1939 SetClipboardData( CF_TEXT
, 0 );
1941 memset( formats
, 0xcc, sizeof(formats
) );
1942 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1943 ok( r
, "gle %d\n", GetLastError() );
1944 ok( count
== 2, "wrong count %u\n", count
);
1945 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
1946 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
1947 ok( formats
[2] == 0xcccccccc, "wrong format %u\n", formats
[2] );
1949 SetLastError( 0xdeadbeef );
1951 r
= pGetUpdatedClipboardFormats( formats
, 0, &count
);
1952 ok( !r
, "succeeded\n" );
1953 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
1954 ok( count
== 2, "wrong count %u\n", count
);
1956 SetLastError( 0xdeadbeef );
1958 r
= pGetUpdatedClipboardFormats( formats
, 1, &count
);
1959 ok( !r
, "succeeded\n" );
1960 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
1961 ok( count
== 2, "wrong count %u\n", count
);
1963 r
= CloseClipboard();
1964 ok( r
, "gle %d\n", GetLastError() );
1967 memset( formats
, 0xcc, sizeof(formats
) );
1968 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1969 ok( r
, "gle %d\n", GetLastError() );
1970 ok( count
== 4, "wrong count %u\n", count
);
1971 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
1972 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
1973 ok( formats
[2] == CF_LOCALE
, "wrong format %u\n", formats
[2] );
1974 ok( formats
[3] == CF_OEMTEXT
, "wrong format %u\n", formats
[3] );
1975 ok( formats
[4] == 0xcccccccc, "wrong format %u\n", formats
[4] );
1978 memset( formats
, 0xcc, sizeof(formats
) );
1979 r
= pGetUpdatedClipboardFormats( formats
, 2, &count
);
1980 ok( !r
, "gle %d\n", GetLastError() );
1981 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
1982 ok( count
== 4, "wrong count %u\n", count
);
1983 ok( formats
[0] == 0xcccccccc, "wrong format %u\n", formats
[0] );
1986 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
1987 ok( !r
, "gle %d\n", GetLastError() );
1988 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1989 ok( count
== 4, "wrong count %u\n", count
);
1992 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
1993 ok( !r
, "gle %d\n", GetLastError() );
1994 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1995 ok( count
== 4, "wrong count %u\n", count
);
1998 START_TEST(clipboard
)
2001 int argc
= winetest_get_mainargs( &argv
);
2002 HMODULE mod
= GetModuleHandleA( "user32" );
2005 pAddClipboardFormatListener
= (void *)GetProcAddress( mod
, "AddClipboardFormatListener" );
2006 pRemoveClipboardFormatListener
= (void *)GetProcAddress( mod
, "RemoveClipboardFormatListener" );
2007 pGetClipboardSequenceNumber
= (void *)GetProcAddress( mod
, "GetClipboardSequenceNumber" );
2008 pGetUpdatedClipboardFormats
= (void *)GetProcAddress( mod
, "GetUpdatedClipboardFormats" );
2010 if (argc
== 4 && !strcmp( argv
[2], "set_clipboard_data" ))
2012 set_clipboard_data_process( atoi( argv
[3] ));
2015 if (argc
== 4 && !strcmp( argv
[2], "grab_clipboard" ))
2017 grab_clipboard_process( atoi( argv
[3] ));
2020 if (argc
== 4 && !strcmp( argv
[2], "handles" ))
2022 test_handles_process( argv
[3] );
2026 test_RegisterClipboardFormatA();
2027 test_ClipboardOwner();
2030 test_data_handles();
2031 test_GetUpdatedClipboardFormats();