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 #define WM_CLIPBOARDUPDATE 0x031D
31 static BOOL (WINAPI
*pAddClipboardFormatListener
)(HWND hwnd
);
32 static BOOL (WINAPI
*pRemoveClipboardFormatListener
)(HWND hwnd
);
33 static BOOL (WINAPI
*pGetUpdatedClipboardFormats
)( UINT
*formats
, UINT count
, UINT
*out_count
);
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 ok( IsClipboardFormatAvailable( CF_WAVE
), "process %u: CF_WAVE not available\n", arg
);
110 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
111 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
115 SetClipboardData( CF_WAVE
, 0 );
116 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
117 arg
, GetLastError());
118 ok( !IsClipboardFormatAvailable( CF_WAVE
), "process %u: SetClipboardData succeeded\n", arg
);
119 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
120 ok( !ret
, "process %u: SetClipboardData succeeded\n", arg
);
121 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
122 arg
, GetLastError());
126 static void grab_clipboard_process( int arg
)
130 SetLastError( 0xdeadbeef );
131 ret
= OpenClipboard( 0 );
132 ok( ret
, "OpenClipboard failed\n" );
133 ret
= EmptyClipboard();
134 ok( ret
, "EmptyClipboard failed\n" );
137 HANDLE ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
138 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
142 static void run_thread( LPTHREAD_START_ROUTINE func
, void *arg
, int line
)
147 thread_from_line
= line
;
148 thread
= CreateThread(NULL
, 0, func
, arg
, 0, NULL
);
149 ok(thread
!= NULL
, "%u: CreateThread failed with error %d\n", line
, GetLastError());
152 ret
= MsgWaitForMultipleObjectsEx( 1, &thread
, 1000, QS_ALLINPUT
, 0 );
153 if (ret
== WAIT_OBJECT_0
+ 1)
156 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
160 ok(ret
== WAIT_OBJECT_0
, "%u: expected WAIT_OBJECT_0, got %u\n", line
, ret
);
164 static void run_process( const char *args
)
167 PROCESS_INFORMATION info
;
168 STARTUPINFOA startup
;
170 sprintf( cmd
, "%s clipboard %s", argv0
, args
);
171 memset( &startup
, 0, sizeof(startup
) );
172 startup
.cb
= sizeof(startup
);
173 ok( CreateProcessA( NULL
, cmd
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &startup
, &info
),
174 "CreateProcess %s failed\n", cmd
);
176 winetest_wait_child_process( info
.hProcess
);
177 CloseHandle( info
.hProcess
);
178 CloseHandle( info
.hThread
);
181 static WNDPROC old_proc
;
182 static LRESULT CALLBACK
winproc_wrapper( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
184 static int wm_renderallformats
;
185 static int wm_drawclipboard
;
187 DWORD msg_flags
= InSendMessageEx( NULL
);
189 if (!seqno
) seqno
= GetClipboardSequenceNumber();
191 trace( "%p msg %04x\n", hwnd
, msg
);
192 if (!wm_renderallformats
)
194 ok( GetClipboardOwner() == hwnd
, "%04x: wrong owner %p/%p\n", msg
, GetClipboardOwner(), hwnd
);
195 ok( seqno
== GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg
);
199 ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg
, GetClipboardOwner() );
200 ok( seqno
+ 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg
);
202 ok( GetClipboardViewer() == hwnd
, "%04x: wrong viewer %p/%p\n", msg
, GetClipboardViewer(), hwnd
);
203 ok( GetOpenClipboardWindow() == hwnd
, "%04x: wrong open win %p/%p\n",
204 msg
, GetOpenClipboardWindow(), hwnd
);
209 ok( wm_renderallformats
, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
210 ok( wm_drawclipboard
, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
212 case WM_DRAWCLIPBOARD
:
213 ok( msg_flags
== ISMEX_NOSEND
, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
216 case WM_RENDERALLFORMATS
:
217 ok( msg_flags
== ISMEX_NOSEND
, "WM_RENDERALLFORMATS wrong flags %x\n", msg_flags
);
218 wm_renderallformats
++;
221 return old_proc( hwnd
, msg
, wp
, lp
);
224 static void test_ClipboardOwner(void)
229 SetLastError(0xdeadbeef);
230 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
231 "could not perform clipboard test: clipboard already owned\n");
233 hWnd1
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
234 0, 0, 10, 10, 0, 0, 0, NULL
);
235 ok(hWnd1
!= 0, "CreateWindowExA error %d\n", GetLastError());
236 trace("hWnd1 = %p\n", hWnd1
);
238 hWnd2
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
239 0, 0, 10, 10, 0, 0, 0, NULL
);
240 ok(hWnd2
!= 0, "CreateWindowExA error %d\n", GetLastError());
241 trace("hWnd2 = %p\n", hWnd2
);
243 SetLastError(0xdeadbeef);
244 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
245 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
246 "wrong error %u\n", GetLastError());
248 ok(OpenClipboard(0), "OpenClipboard failed\n");
249 ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
250 ok(!OpenClipboard(hWnd1
), "OpenClipboard should fail since clipboard already opened\n");
251 ok(OpenClipboard(0), "OpenClipboard again failed\n");
252 ret
= CloseClipboard();
253 ok( ret
, "CloseClipboard error %d\n", GetLastError());
255 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
256 run_thread( open_clipboard_thread
, hWnd1
, __LINE__
);
257 run_thread( empty_clipboard_thread
, 0, __LINE__
);
258 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
259 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
260 ok( !GetClipboardData( CF_WAVE
), "CF_WAVE data available\n" );
261 run_process( "set_clipboard_data 0" );
262 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
263 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
265 SetLastError(0xdeadbeef);
266 ret
= OpenClipboard(hWnd2
);
267 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
268 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
270 SetLastError(0xdeadbeef);
271 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
272 ret
= EmptyClipboard();
273 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
274 ok(GetClipboardOwner() == hWnd1
, "clipboard should be owned by %p, not by %p\n", hWnd1
, GetClipboardOwner());
275 run_thread( empty_clipboard_thread
, 0, __LINE__
);
276 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
277 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
278 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
279 run_process( "set_clipboard_data 1" );
281 SetLastError(0xdeadbeef);
282 ret
= OpenClipboard(hWnd2
);
283 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
284 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
286 ret
= CloseClipboard();
287 ok( ret
, "CloseClipboard error %d\n", GetLastError());
288 ok(GetClipboardOwner() == hWnd1
, "clipboard should still be owned\n");
290 /* any window will do, even from a different process */
291 ret
= OpenClipboard( GetDesktopWindow() );
292 ok( ret
, "OpenClipboard error %d\n", GetLastError());
293 ret
= EmptyClipboard();
294 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
295 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
296 GetClipboardOwner(), GetDesktopWindow() );
297 run_thread( set_clipboard_data_thread
, GetDesktopWindow(), __LINE__
);
298 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
299 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
300 run_process( "set_clipboard_data 2" );
301 ret
= CloseClipboard();
302 ok( ret
, "CloseClipboard error %d\n", GetLastError());
304 ret
= OpenClipboard( hWnd1
);
305 ok( ret
, "OpenClipboard error %d\n", GetLastError());
306 ret
= EmptyClipboard();
307 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
308 SetClipboardData( CF_WAVE
, 0 );
309 SetClipboardViewer( hWnd1
);
310 ok( GetClipboardOwner() == hWnd1
, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1
);
311 ok( GetClipboardViewer() == hWnd1
, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1
);
312 ok( GetOpenClipboardWindow() == hWnd1
, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1
);
313 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
315 old_proc
= (WNDPROC
)SetWindowLongPtrA( hWnd1
, GWLP_WNDPROC
, (LONG_PTR
)winproc_wrapper
);
316 ret
= DestroyWindow(hWnd1
);
317 ok( ret
, "DestroyWindow error %d\n", GetLastError());
318 ret
= DestroyWindow(hWnd2
);
319 ok( ret
, "DestroyWindow error %d\n", GetLastError());
320 SetLastError(0xdeadbeef);
321 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
322 ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n");
323 ok(!GetOpenClipboardWindow() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n");
324 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
326 SetLastError( 0xdeadbeef );
327 ret
= CloseClipboard();
328 ok( !ret
, "CloseClipboard succeeded\n" );
329 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
331 ret
= OpenClipboard( 0 );
332 ok( ret
, "OpenClipboard error %d\n", GetLastError());
333 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
334 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
335 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
336 run_process( "set_clipboard_data 3" );
337 ret
= CloseClipboard();
338 ok( ret
, "CloseClipboard error %d\n", GetLastError());
340 run_thread( open_and_empty_clipboard_thread
, 0, __LINE__
);
341 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
342 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
344 ret
= OpenClipboard( 0 );
345 ok( ret
, "OpenClipboard error %d\n", GetLastError());
346 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
347 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
348 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
349 run_process( "set_clipboard_data 4" );
350 ret
= EmptyClipboard();
351 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
352 ret
= CloseClipboard();
353 ok( ret
, "CloseClipboard error %d\n", GetLastError());
355 SetLastError( 0xdeadbeef );
356 ok( !SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 )),
357 "SetClipboardData succeeded\n" );
358 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
359 ok( !IsClipboardFormatAvailable( CF_WAVE
), "SetClipboardData succeeded\n" );
361 run_thread( open_and_empty_clipboard_thread
, GetDesktopWindow(), __LINE__
);
362 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
363 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n",
364 GetClipboardOwner(), GetDesktopWindow() );
366 run_thread( open_and_empty_clipboard_win_thread
, 0, __LINE__
);
367 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
368 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
371 static void test_RegisterClipboardFormatA(void)
374 UINT format_id
, format_id2
;
380 format_id
= RegisterClipboardFormatA("my_cool_clipboard_format");
381 ok(format_id
> 0xc000 && format_id
< 0xffff, "invalid clipboard format id %04x\n", format_id
);
383 format_id2
= RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
384 ok(format_id2
== format_id
, "invalid clipboard format id %04x\n", format_id2
);
386 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
387 ok(len
== lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len
);
388 ok(!lstrcmpA(buf
, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf
);
390 lstrcpyA(buf
, "foo");
391 SetLastError(0xdeadbeef);
392 len
= GetAtomNameA((ATOM
)format_id
, buf
, 256);
393 ok(len
== 0, "GetAtomNameA should fail\n");
394 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
398 lstrcpyA(buf
, "foo");
399 SetLastError(0xdeadbeef);
400 len
= GlobalGetAtomNameA((ATOM
)format_id
, buf
, 256);
401 ok(len
== 0, "GlobalGetAtomNameA should fail\n");
402 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
405 SetLastError(0xdeadbeef);
406 atom_id
= FindAtomA("my_cool_clipboard_format");
407 ok(atom_id
== 0, "FindAtomA should fail\n");
408 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
412 /* this relies on the clipboard and global atom table being different */
413 SetLastError(0xdeadbeef);
414 atom_id
= GlobalFindAtomA("my_cool_clipboard_format");
415 ok(atom_id
== 0, "GlobalFindAtomA should fail\n");
416 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
419 for (format_id
= 0; format_id
< 0x10fff; format_id
++)
421 SetLastError(0xdeadbeef);
422 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
424 if (format_id
< 0xc000 || format_id
> 0xffff)
425 ok(!len
, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len
, buf
);
426 else if (len
&& winetest_debug
> 1)
427 trace("%04x: %s\n", format_id
, len
? buf
: "");
430 ret
= OpenClipboard(0);
431 ok( ret
, "OpenClipboard error %d\n", GetLastError());
433 /* try some invalid/unregistered formats */
434 SetLastError( 0xdeadbeef );
435 handle
= SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
436 ok( !handle
, "SetClipboardData succeeded\n" );
437 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError());
438 handle
= SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
439 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
440 handle
= SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
441 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
442 handle
= SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
443 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
445 ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
446 ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
447 ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
448 ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
449 ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
450 ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
452 trace("# of formats available: %d\n", CountClipboardFormats());
455 while ((format_id
= EnumClipboardFormats(format_id
)))
457 ok(IsClipboardFormatAvailable(format_id
), "format %04x was listed as available\n", format_id
);
458 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
459 trace("%04x: %s\n", format_id
, len
? buf
: "");
462 ret
= EmptyClipboard();
463 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
464 ret
=CloseClipboard();
465 ok( ret
, "CloseClipboard error %d\n", GetLastError());
467 if (CountClipboardFormats())
469 SetLastError(0xdeadbeef);
470 ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
471 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
,
472 "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError());
475 SetLastError(0xdeadbeef);
476 ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
477 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
478 "Wrong error %u\n", GetLastError());
480 format_id
= RegisterClipboardFormatA("#1234");
481 ok(format_id
== 1234, "invalid clipboard format id %04x\n", format_id
);
484 static HGLOBAL
create_textA(void)
486 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, 10);
487 char *p
= GlobalLock(h
);
488 memcpy(p
, "test\0\0\0\0\0", 10);
493 static HGLOBAL
create_textW(void)
495 static const WCHAR testW
[] = {'t','e','s','t',0,0,0,0,0,0};
496 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, sizeof(testW
));
497 WCHAR
*p
= GlobalLock(h
);
498 memcpy(p
, testW
, sizeof(testW
));
503 static HANDLE
create_metafile(void)
505 const RECT rect
= {0, 0, 100, 100};
509 HDC hdc
= CreateMetaFileA( NULL
);
510 ExtTextOutA( hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
511 mf
= CloseMetaFile( hdc
);
512 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, sizeof(*pict
) );
513 pict
= GlobalLock( ret
);
515 pict
->xExt
= pict
->yExt
= 100;
521 static HENHMETAFILE
create_emf(void)
523 const RECT rect
= {0, 0, 100, 100};
524 HDC hdc
= CreateEnhMetaFileA(NULL
, NULL
, &rect
, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
525 ExtTextOutA(hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
526 return CloseEnhMetaFile(hdc
);
529 static HBITMAP
create_bitmap(void)
531 HDC hdc
= GetDC( 0 );
532 UINT bpp
= GetDeviceCaps( hdc
, BITSPIXEL
);
534 return CreateBitmap( 10, 10, 1, bpp
, NULL
);
537 static HBITMAP
create_dib( BOOL v5
)
540 BITMAPINFOHEADER
*hdr
;
542 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
| GMEM_ZEROINIT
,
543 sizeof(BITMAPV5HEADER
) + 256 * sizeof(RGBQUAD
) + 16 * 16 * 4 );
544 hdr
= GlobalLock( ret
);
545 hdr
->biSize
= v5
? sizeof(BITMAPV5HEADER
) : sizeof(*hdr
);
549 hdr
->biBitCount
= 32;
550 hdr
->biCompression
= BI_RGB
;
553 BITMAPV5HEADER
*hdr5
= (BITMAPV5HEADER
*)hdr
;
554 hdr5
->bV5RedMask
= 0x0000ff;
555 hdr5
->bV5GreenMask
= 0x00ff00;
556 hdr5
->bV5BlueMask
= 0xff0000;
557 hdr5
->bV5AlphaMask
= 0xff000000;
563 static LRESULT CALLBACK
renderer_winproc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
565 static UINT rendered
;
570 case WM_RENDERFORMAT
:
571 if (wp
< 32) rendered
|= (1 << wp
);
578 return DefWindowProcA( hwnd
, msg
, wp
, lp
);
581 static void test_synthesized(void)
583 static const struct test
589 /* 0 */ { CF_TEXT
, { CF_TEXT
, CF_LOCALE
, CF_OEMTEXT
, CF_UNICODETEXT
}},
590 { CF_OEMTEXT
, { CF_OEMTEXT
, CF_LOCALE
, CF_TEXT
, CF_UNICODETEXT
}},
591 { CF_UNICODETEXT
, { CF_UNICODETEXT
, CF_LOCALE
, CF_TEXT
, CF_OEMTEXT
}},
592 { CF_ENHMETAFILE
, { CF_ENHMETAFILE
, CF_METAFILEPICT
}},
593 { CF_METAFILEPICT
, { CF_METAFILEPICT
, CF_ENHMETAFILE
}},
594 /* 5 */ { CF_BITMAP
, { CF_BITMAP
, CF_DIB
, CF_DIBV5
}},
595 { CF_DIB
, { CF_DIB
, CF_BITMAP
, CF_DIBV5
}},
596 { CF_DIBV5
, { CF_DIBV5
, CF_BITMAP
, CF_DIB
}},
602 UINT cf
, i
, j
, count
, rendered
, seq
, old_seq
;
606 hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
607 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)renderer_winproc
);
609 htext
= create_textA();
612 r
= OpenClipboard(NULL
);
613 ok(r
, "gle %d\n", GetLastError());
614 r
= EmptyClipboard();
615 ok(r
, "gle %d\n", GetLastError());
616 h
= SetClipboardData(CF_TEXT
, htext
);
617 ok(h
== htext
, "got %p\n", h
);
618 h
= SetClipboardData(CF_ENHMETAFILE
, emf
);
619 ok(h
== emf
, "got %p\n", h
);
620 r
= CloseClipboard();
621 ok(r
, "gle %d\n", GetLastError());
623 count
= CountClipboardFormats();
624 ok( count
== 6, "count %u\n", count
);
625 r
= IsClipboardFormatAvailable( CF_TEXT
);
626 ok( r
, "CF_TEXT not available err %d\n", GetLastError());
627 r
= IsClipboardFormatAvailable( CF_LOCALE
);
628 ok( r
, "CF_LOCALE not available err %d\n", GetLastError());
629 r
= IsClipboardFormatAvailable( CF_OEMTEXT
);
630 ok( r
, "CF_OEMTEXT not available err %d\n", GetLastError());
631 r
= IsClipboardFormatAvailable( CF_UNICODETEXT
);
632 ok( r
, "CF_UNICODETEXT not available err %d\n", GetLastError());
633 r
= IsClipboardFormatAvailable( CF_ENHMETAFILE
);
634 ok( r
, "CF_ENHMETAFILE not available err %d\n", GetLastError());
635 r
= IsClipboardFormatAvailable( CF_METAFILEPICT
);
636 ok( r
, "CF_METAFILEPICT not available err %d\n", GetLastError());
638 r
= OpenClipboard(NULL
);
639 ok(r
, "gle %d\n", GetLastError());
640 cf
= EnumClipboardFormats(0);
641 ok(cf
== CF_TEXT
, "cf %08x\n", cf
);
642 data
= GetClipboardData(cf
);
643 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
645 cf
= EnumClipboardFormats(cf
);
646 ok(cf
== CF_ENHMETAFILE
, "cf %08x\n", cf
);
647 data
= GetClipboardData(cf
);
648 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
650 cf
= EnumClipboardFormats(cf
);
651 ok(cf
== CF_LOCALE
, "cf %08x\n", cf
);
652 data
= GetClipboardData(cf
);
653 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
655 cf
= EnumClipboardFormats(cf
);
656 ok(cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
657 data
= GetClipboardData(cf
);
658 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
660 cf
= EnumClipboardFormats(cf
);
661 ok(cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
663 cf
= EnumClipboardFormats(cf
);
664 ok(cf
== CF_METAFILEPICT
, "cf %08x\n", cf
);
665 data
= GetClipboardData(cf
);
666 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
668 cf
= EnumClipboardFormats(cf
);
669 ok(cf
== 0, "cf %08x\n", cf
);
671 r
= EmptyClipboard();
672 ok(r
, "gle %d\n", GetLastError());
674 SetClipboardData( CF_UNICODETEXT
, create_textW() );
675 SetClipboardData( CF_TEXT
, create_textA() );
676 SetClipboardData( CF_OEMTEXT
, create_textA() );
677 r
= CloseClipboard();
678 ok(r
, "gle %d\n", GetLastError());
680 r
= OpenClipboard( NULL
);
681 ok(r
, "gle %d\n", GetLastError());
682 SetLastError( 0xdeadbeef );
683 cf
= EnumClipboardFormats(0);
684 ok( cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
685 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
686 SetLastError( 0xdeadbeef );
687 cf
= EnumClipboardFormats(cf
);
688 ok( cf
== CF_TEXT
, "cf %08x\n", cf
);
689 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
690 SetLastError( 0xdeadbeef );
691 cf
= EnumClipboardFormats(cf
);
692 ok( cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
693 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
694 SetLastError( 0xdeadbeef );
695 cf
= EnumClipboardFormats(cf
);
696 ok( cf
== CF_LOCALE
, "cf %08x\n", cf
);
697 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
698 SetLastError( 0xdeadbeef );
699 cf
= EnumClipboardFormats( cf
);
700 ok( cf
== 0, "cf %08x\n", cf
);
701 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
702 SetLastError( 0xdeadbeef );
703 cf
= EnumClipboardFormats( 0xdead );
704 ok( cf
== 0, "cf %08x\n", cf
);
705 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
707 r
= EmptyClipboard();
708 ok(r
, "gle %d\n", GetLastError());
710 r
= CloseClipboard();
711 ok(r
, "gle %d\n", GetLastError());
713 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
715 r
= OpenClipboard(NULL
);
716 ok(r
, "%u: gle %d\n", i
, GetLastError());
717 r
= EmptyClipboard();
718 ok(r
, "%u: gle %d\n", i
, GetLastError());
720 switch (tests
[i
].format
)
724 SetClipboardData( tests
[i
].format
, create_textA() );
727 SetClipboardData( CF_UNICODETEXT
, create_textW() );
730 SetClipboardData( CF_ENHMETAFILE
, create_emf() );
732 case CF_METAFILEPICT
:
733 SetClipboardData( CF_METAFILEPICT
, create_metafile() );
736 SetClipboardData( CF_BITMAP
, create_bitmap() );
740 SetClipboardData( tests
[i
].format
, create_dib( tests
[i
].format
== CF_DIBV5
));
744 count
= CountClipboardFormats();
745 ok( count
== 1, "%u: count %u\n", i
, count
);
747 r
= CloseClipboard();
748 ok(r
, "%u: gle %d\n", i
, GetLastError());
750 count
= CountClipboardFormats();
751 for (j
= 0; tests
[i
].expected
[j
]; j
++)
753 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
754 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
756 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
758 r
= OpenClipboard( hwnd
);
759 ok(r
, "%u: gle %d\n", i
, GetLastError());
761 for (j
= 0; tests
[i
].expected
[j
]; j
++)
763 cf
= EnumClipboardFormats( cf
);
764 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
765 i
, j
, cf
, tests
[i
].expected
[j
] );
766 if (cf
!= tests
[i
].expected
[j
]) break;
767 old_seq
= GetClipboardSequenceNumber();
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());
772 seq
= GetClipboardSequenceNumber();
773 ok(seq
== old_seq
, "sequence changed (test %d %d)\n", i
, cf
);
778 UINT
*ptr
= GlobalLock( data
);
779 ok( GlobalSize( data
) == sizeof(*ptr
), "%u: size %lu\n", i
, GlobalSize( data
));
780 ok( *ptr
== GetUserDefaultLCID() ||
781 broken( *ptr
== MAKELANGID( LANG_ENGLISH
, SUBLANG_DEFAULT
)),
782 "%u: CF_LOCALE %08x/%08x\n", i
, *ptr
, GetUserDefaultLCID() );
783 GlobalUnlock( data
);
788 ok( GlobalSize( data
) == 10, "wrong len %ld\n", GlobalSize( data
));
791 ok( GlobalSize( data
) == 10 * sizeof(WCHAR
), "wrong len %ld\n", GlobalSize( data
));
795 if (!tests
[i
].expected
[j
])
797 cf
= EnumClipboardFormats( cf
);
798 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
801 /* now with delayed rendering */
803 r
= EmptyClipboard();
804 ok(r
, "%u: gle %d\n", i
, GetLastError());
806 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
807 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
809 SetClipboardData( tests
[i
].format
, 0 );
810 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
811 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
813 count
= CountClipboardFormats();
814 ok( count
== 1, "%u: count %u\n", i
, count
);
816 r
= CloseClipboard();
817 ok(r
, "%u: gle %d\n", i
, GetLastError());
818 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
819 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
821 count
= CountClipboardFormats();
822 for (j
= 0; tests
[i
].expected
[j
]; j
++)
824 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
825 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
827 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
828 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
829 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
831 r
= OpenClipboard(NULL
);
832 ok(r
, "%u: gle %d\n", i
, GetLastError());
834 for (j
= 0; tests
[i
].expected
[j
]; j
++)
836 cf
= EnumClipboardFormats( cf
);
837 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
838 i
, j
, cf
, tests
[i
].expected
[j
] );
839 if (cf
!= tests
[i
].expected
[j
]) break;
840 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
841 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
842 data
= GetClipboardData( cf
);
843 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
846 ok(data
!= NULL
, "%u: CF_LOCALE no data\n", i
);
847 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
851 ok(!data
, "%u: format %04x got data %p\n", i
, cf
, data
);
852 ok( rendered
== (1 << tests
[i
].format
),
853 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
854 /* try to render a second time */
855 data
= GetClipboardData( cf
);
856 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
857 ok( rendered
== (1 << tests
[i
].format
),
858 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
861 if (!tests
[i
].expected
[j
])
863 cf
= EnumClipboardFormats( cf
);
864 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
866 r
= CloseClipboard();
867 ok(r
, "%u: gle %d\n", i
, GetLastError());
868 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
869 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
872 r
= OpenClipboard(NULL
);
873 ok(r
, "gle %d\n", GetLastError());
874 r
= EmptyClipboard();
875 ok(r
, "gle %d\n", GetLastError());
876 r
= CloseClipboard();
877 ok(r
, "gle %d\n", GetLastError());
878 DestroyWindow( hwnd
);
881 static DWORD WINAPI
clipboard_render_data_thread(void *param
)
883 HANDLE handle
= SetClipboardData( CF_UNICODETEXT
, create_textW() );
884 ok( handle
!= 0, "SetClipboardData failed: %d\n", GetLastError() );
888 static CRITICAL_SECTION clipboard_cs
;
889 static HWND next_wnd
;
890 static UINT wm_drawclipboard
;
891 static UINT wm_clipboardupdate
;
892 static UINT wm_destroyclipboard
;
893 static UINT wm_renderformat
;
894 static UINT nb_formats
;
895 static BOOL cross_thread
;
896 static BOOL do_render_format
;
898 static LRESULT CALLBACK
clipboard_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
901 DWORD msg_flags
= InSendMessageEx( NULL
);
904 case WM_DRAWCLIPBOARD
:
905 ok( msg_flags
== (cross_thread
? ISMEX_NOTIFY
: ISMEX_NOSEND
),
906 "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
907 EnterCriticalSection(&clipboard_cs
);
909 LeaveCriticalSection(&clipboard_cs
);
911 case WM_CHANGECBCHAIN
:
912 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
913 "WM_CHANGECBCHAIN wrong flags %x\n", msg_flags
);
914 if (next_wnd
== (HWND
)wp
)
917 SendMessageA(next_wnd
, msg
, wp
, lp
);
919 case WM_DESTROYCLIPBOARD
:
920 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
921 "WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags
);
922 wm_destroyclipboard
++;
923 ok( GetClipboardOwner() == hwnd
, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
924 nb_formats
= CountClipboardFormats();
926 case WM_RENDERFORMAT
:
927 ok( !wm_renderformat
, "multiple WM_RENDERFORMAT %04x / %04lx\n", wm_renderformat
, wp
);
928 wm_renderformat
= wp
;
930 if (do_render_format
)
935 old_seq
= GetClipboardSequenceNumber();
936 handle
= SetClipboardData( CF_TEXT
, create_textA() );
937 ok( handle
!= 0, "SetClipboardData failed: %d\n", GetLastError() );
938 seq
= GetClipboardSequenceNumber();
939 ok( seq
== old_seq
, "sequence changed\n" );
942 handle
= CreateThread( NULL
, 0, clipboard_render_data_thread
, NULL
, 0, NULL
);
943 ok( handle
!= NULL
, "CreateThread failed: %d\n", GetLastError() );
944 ok( WaitForSingleObject(handle
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
945 CloseHandle( handle
);
946 seq
= GetClipboardSequenceNumber();
947 ok( seq
== old_seq
, "sequence changed\n" );
951 case WM_CLIPBOARDUPDATE
:
952 ok( msg_flags
== ISMEX_NOSEND
, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags
);
953 EnterCriticalSection(&clipboard_cs
);
954 wm_clipboardupdate
++;
955 LeaveCriticalSection(&clipboard_cs
);
958 ChangeClipboardChain(hwnd
, next_wnd
);
962 ret
= wm_drawclipboard
;
963 wm_drawclipboard
= 0;
966 ret
= wm_clipboardupdate
;
967 wm_clipboardupdate
= 0;
970 ret
= wm_destroyclipboard
;
971 wm_destroyclipboard
= 0;
974 ret
= wm_renderformat
;
981 return DefWindowProcA(hwnd
, msg
, wp
, lp
);
984 static void get_clipboard_data_process(void)
989 r
= OpenClipboard(0);
990 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
991 data
= GetClipboardData( CF_UNICODETEXT
);
992 ok( data
!= NULL
, "GetClipboardData failed: %d\n", GetLastError());
993 r
= CloseClipboard();
994 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
997 static DWORD WINAPI
clipboard_thread(void *param
)
999 HWND ret
, win
= param
;
1003 UINT count
, fmt
, formats
, old_seq
= 0, seq
;
1005 cross_thread
= (GetWindowThreadProcessId( win
, NULL
) != GetCurrentThreadId());
1006 trace( "%s-threaded test\n", cross_thread
? "multi" : "single" );
1008 old_seq
= GetClipboardSequenceNumber();
1010 EnterCriticalSection(&clipboard_cs
);
1011 SetLastError(0xdeadbeef);
1012 next_wnd
= SetClipboardViewer(win
);
1013 ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
1014 LeaveCriticalSection(&clipboard_cs
);
1016 SetLastError( 0xdeadbeef );
1017 ret
= SetClipboardViewer( (HWND
)0xdead );
1018 ok( !ret
, "SetClipboardViewer succeeded\n" );
1019 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1020 SetLastError( 0xdeadbeef );
1021 r
= ChangeClipboardChain( win
, (HWND
)0xdead );
1022 ok( !r
, "ChangeClipboardChain succeeded\n" );
1023 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1024 SetLastError( 0xdeadbeef );
1025 r
= ChangeClipboardChain( (HWND
)0xdead, next_wnd
);
1026 ok( !r
, "ChangeClipboardChain succeeded\n" );
1027 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1029 if (pAddClipboardFormatListener
)
1031 r
= pAddClipboardFormatListener(win
);
1032 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
1033 SetLastError( 0xdeadbeef );
1034 r
= pAddClipboardFormatListener( win
);
1035 ok( !r
, "AddClipboardFormatListener succeeded\n" );
1036 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1037 SetLastError( 0xdeadbeef );
1038 r
= pAddClipboardFormatListener( (HWND
)0xdead );
1039 ok( !r
, "AddClipboardFormatListener succeeded\n" );
1040 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1041 r
= pAddClipboardFormatListener( GetDesktopWindow() );
1042 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
1043 r
= pRemoveClipboardFormatListener( GetDesktopWindow() );
1044 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1047 seq
= GetClipboardSequenceNumber();
1048 ok( seq
== old_seq
, "sequence changed\n" );
1051 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1052 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1053 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1054 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1056 count
= SendMessageA( win
, WM_USER
+ 1, 0, 0 );
1057 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1058 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1059 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1060 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1061 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1063 SetLastError( 0xdeadbeef );
1064 r
= OpenClipboard( (HWND
)0xdead );
1065 ok( !r
, "OpenClipboard succeeded\n" );
1066 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1068 r
= OpenClipboard(win
);
1069 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1071 seq
= GetClipboardSequenceNumber();
1072 ok( seq
== old_seq
, "sequence changed\n" );
1075 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1076 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1077 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1078 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1080 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1081 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1082 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1083 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1084 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1085 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1087 r
= EmptyClipboard();
1088 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1090 seq
= GetClipboardSequenceNumber();
1091 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1095 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1096 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1097 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1098 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1100 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1101 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1102 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1103 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1104 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1105 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1106 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1107 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1109 r
= EmptyClipboard();
1110 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1111 /* sequence changes again, even though it was already empty */
1112 seq
= GetClipboardSequenceNumber();
1113 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1117 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1118 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1119 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1120 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1122 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1123 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1124 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1125 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1126 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1127 ok( count
, "WM_DESTROYCLIPBOARD not received\n" );
1128 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1129 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1130 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1131 ok( !count
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1133 handle
= SetClipboardData( CF_TEXT
, create_textA() );
1134 ok(handle
!= 0, "SetClipboardData failed: %d\n", GetLastError());
1136 seq
= GetClipboardSequenceNumber();
1137 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1141 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1142 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1143 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1144 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1146 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1147 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1148 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1149 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1150 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1151 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1153 SetClipboardData( CF_UNICODETEXT
, 0 );
1155 seq
= GetClipboardSequenceNumber();
1156 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1160 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1161 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1162 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1163 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1165 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1166 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1167 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1168 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1169 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1170 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1172 SetClipboardData( CF_UNICODETEXT
, 0 ); /* same data again */
1174 seq
= GetClipboardSequenceNumber();
1175 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1179 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1180 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1181 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1182 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1184 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1185 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1186 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1187 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1188 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1189 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1191 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1192 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1193 ok( !IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1195 EnterCriticalSection(&clipboard_cs
);
1196 r
= CloseClipboard();
1197 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1198 LeaveCriticalSection(&clipboard_cs
);
1200 seq
= GetClipboardSequenceNumber();
1201 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1205 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1206 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1207 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1208 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1210 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1211 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1212 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1213 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1214 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1215 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1217 r
= OpenClipboard(win
);
1218 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1220 seq
= GetClipboardSequenceNumber();
1221 ok( seq
== old_seq
, "sequence changed\n" );
1224 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1225 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1226 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1228 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1229 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1230 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1231 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1232 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1233 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1235 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1236 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1237 ok( IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1239 ok( GetClipboardOwner() == win
, "wrong owner %p\n", GetClipboardOwner());
1240 handle
= GetClipboardData( CF_UNICODETEXT
);
1241 ok( !handle
, "got data for CF_UNICODETEXT\n" );
1242 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1243 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1245 do_render_format
= TRUE
;
1246 handle
= GetClipboardData( CF_OEMTEXT
);
1247 ok( handle
!= NULL
, "didn't get data for CF_OEMTEXT\n" );
1248 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1249 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1250 do_render_format
= FALSE
;
1252 SetClipboardData( CF_WAVE
, 0 );
1253 seq
= GetClipboardSequenceNumber();
1254 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1258 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1259 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1260 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1261 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1263 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1264 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1265 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1266 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1267 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1268 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1270 r
= CloseClipboard();
1271 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1272 /* no synthesized format, so CloseClipboard doesn't change the sequence */
1273 seq
= GetClipboardSequenceNumber();
1274 ok( seq
== old_seq
, "sequence changed\n" );
1278 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not 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
== 1, "WM_DRAWCLIPBOARD not received\n" );
1285 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1286 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1287 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1288 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1290 r
= OpenClipboard(win
);
1291 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1292 r
= CloseClipboard();
1293 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1294 /* nothing changed */
1295 seq
= GetClipboardSequenceNumber();
1296 ok( seq
== old_seq
, "sequence changed\n" );
1299 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1300 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1301 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1302 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1304 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1305 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1306 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1307 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1308 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1309 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1310 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1311 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1313 formats
= CountClipboardFormats();
1314 r
= OpenClipboard(0);
1315 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1316 r
= EmptyClipboard();
1317 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1318 r
= CloseClipboard();
1319 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1323 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1324 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1325 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1326 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1328 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1329 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1330 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1331 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1332 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1333 ok( count
== 1, "WM_DESTROYCLIPBOARD not received\n" );
1334 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1335 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1336 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1337 ok( count
== formats
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1339 r
= OpenClipboard(win
);
1340 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1341 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1342 seq
= GetClipboardSequenceNumber();
1343 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1347 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1348 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1349 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1350 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1352 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1353 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1354 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1355 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1356 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
1357 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
1358 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1359 ok( !fmt
, "WM_RENDERFORMAT received %04x\n", fmt
);
1361 EnterCriticalSection(&clipboard_cs
);
1362 r
= CloseClipboard();
1363 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1364 LeaveCriticalSection(&clipboard_cs
);
1366 seq
= GetClipboardSequenceNumber();
1367 ok( seq
== old_seq
, "sequence changed\n" );
1371 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1372 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1373 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1374 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1376 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1377 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1378 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1379 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1380 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1381 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1383 run_process( "grab_clipboard 0" );
1385 seq
= GetClipboardSequenceNumber();
1386 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1390 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1391 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1392 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1393 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1394 cross_thread
= TRUE
;
1395 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1396 cross_thread
= FALSE
;
1398 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1399 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1400 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1401 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1402 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1403 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1405 r
= OpenClipboard(0);
1406 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1407 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1408 seq
= GetClipboardSequenceNumber();
1409 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 seq
= GetClipboardSequenceNumber();
1431 ok( seq
== old_seq
, "sequence changed\n" );
1435 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD received\n" );
1436 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1437 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1438 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1440 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1441 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1442 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1443 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1444 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1445 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1447 run_process( "grab_clipboard 1" );
1449 seq
= GetClipboardSequenceNumber();
1450 ok( (int)(seq
- old_seq
) == 2, "sequence diff %d\n", seq
- old_seq
);
1454 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1455 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1456 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1457 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1458 cross_thread
= TRUE
;
1459 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1460 cross_thread
= FALSE
;
1462 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1463 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1464 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1465 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1466 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1467 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1469 r
= OpenClipboard(0);
1470 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1471 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1472 seq
= GetClipboardSequenceNumber();
1473 ok( (int)(seq
- old_seq
) == 1, "sequence diff %d\n", seq
- old_seq
);
1477 ok( !wm_drawclipboard
, "WM_DRAWCLIPBOARD received\n" );
1478 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1479 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1480 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1482 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1483 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
1484 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1485 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
1486 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1487 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1489 EnterCriticalSection(&clipboard_cs
);
1490 r
= CloseClipboard();
1491 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1492 LeaveCriticalSection(&clipboard_cs
);
1494 seq
= GetClipboardSequenceNumber();
1495 ok( seq
== old_seq
, "sequence changed\n" );
1499 ok( wm_drawclipboard
== 1, "WM_DRAWCLIPBOARD not received\n" );
1500 ok( !wm_clipboardupdate
, "WM_CLIPBOARDUPDATE received\n" );
1501 ok( !wm_renderformat
, "WM_RENDERFORMAT received\n" );
1502 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1504 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1505 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1506 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1507 ok( count
== 1 || broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
1508 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1509 ok( !fmt
, "WM_RENDERFORMAT received\n" );
1513 r
= OpenClipboard( win
);
1514 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1515 r
= EmptyClipboard();
1516 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1517 SetClipboardData( CF_TEXT
, 0 );
1518 r
= CloseClipboard();
1519 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1521 do_render_format
= TRUE
;
1522 old_seq
= GetClipboardSequenceNumber();
1523 run_process( "get_clipboard_data" );
1524 seq
= GetClipboardSequenceNumber();
1525 ok( seq
== old_seq
, "sequence changed\n" );
1526 do_render_format
= FALSE
;
1528 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
1529 ok( count
== 1, "WM_DRAWCLIPBOARD not received\n" );
1530 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
1531 ok( count
== 1 || broken(!pAddClipboardFormatListener
) /* < Vista */, "WM_CLIPBOARDUPDATE not received\n" );
1532 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1533 ok( fmt
== CF_TEXT
, "WM_RENDERFORMAT received\n" );
1536 r
= PostMessageA(win
, WM_USER
, 0, 0);
1537 ok(r
, "PostMessage failed: %d\n", GetLastError());
1539 if (pRemoveClipboardFormatListener
)
1541 r
= pRemoveClipboardFormatListener(win
);
1542 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1543 SetLastError( 0xdeadbeef );
1544 r
= pRemoveClipboardFormatListener(win
);
1545 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1546 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1547 SetLastError( 0xdeadbeef );
1548 r
= pRemoveClipboardFormatListener( (HWND
)0xdead );
1549 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1550 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1555 static void test_messages(void)
1563 InitializeCriticalSection(&clipboard_cs
);
1565 memset(&cls
, 0, sizeof(cls
));
1566 cls
.lpfnWndProc
= clipboard_wnd_proc
;
1567 cls
.hInstance
= GetModuleHandleA(NULL
);
1568 cls
.lpszClassName
= "clipboard_test";
1569 RegisterClassA(&cls
);
1571 win
= CreateWindowA("clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0);
1572 ok(win
!= NULL
, "CreateWindow failed: %d\n", GetLastError());
1574 thread
= CreateThread(NULL
, 0, clipboard_thread
, (void*)win
, 0, &tid
);
1575 ok(thread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1577 while(GetMessageA(&msg
, NULL
, 0, 0))
1579 ok( msg
.message
!= WM_DRAWCLIPBOARD
, "WM_DRAWCLIPBOARD was posted\n" );
1580 TranslateMessage(&msg
);
1581 DispatchMessageA(&msg
);
1584 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
1585 CloseHandle(thread
);
1587 DestroyWindow( win
);
1589 /* same tests again but inside a single thread */
1591 win
= CreateWindowA( "clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0 );
1592 ok( win
!= NULL
, "CreateWindow failed: %d\n", GetLastError() );
1594 clipboard_thread( win
);
1595 DestroyWindow( win
);
1597 UnregisterClassA("clipboard_test", GetModuleHandleA(NULL
));
1598 DeleteCriticalSection(&clipboard_cs
);
1601 static BOOL
is_moveable( HANDLE handle
)
1603 void *ptr
= GlobalLock( handle
);
1604 if (ptr
) GlobalUnlock( handle
);
1605 return ptr
&& ptr
!= handle
;
1608 static BOOL
is_fixed( HANDLE handle
)
1610 void *ptr
= GlobalLock( handle
);
1611 if (ptr
) GlobalUnlock( handle
);
1612 return ptr
&& ptr
== handle
;
1615 static BOOL
is_freed( HANDLE handle
)
1617 return !GlobalSize( handle
);
1620 static UINT format_id
;
1621 static HBITMAP bitmap
, bitmap2
;
1622 static HPALETTE palette
;
1623 static const LOGPALETTE logpalette
= { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}};
1625 static void test_handles( HWND hwnd
)
1627 HGLOBAL h
, htext
, htext2
, htext3
, htext4
, htext5
;
1628 HGLOBAL hfixed
, hfixed2
, hmoveable
, empty_fixed
, empty_moveable
;
1630 UINT format_id2
= RegisterClipboardFormatA( "another format" );
1633 HBITMAP bitmap_temp
;
1635 BOOL is_owner
= (GetWindowThreadProcessId( hwnd
, &process
) && process
== GetCurrentProcessId());
1637 trace( "hwnd %p\n", hwnd
);
1638 htext
= create_textA();
1639 htext2
= create_textA();
1640 htext3
= create_textA();
1641 htext4
= create_textA();
1642 htext5
= create_textA();
1643 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
1644 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
1645 palette
= CreatePalette( &logpalette
);
1647 hfixed
= GlobalAlloc( GMEM_FIXED
, 17 );
1648 hfixed2
= GlobalAlloc( GMEM_FIXED
, 17 );
1649 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1650 ok( GlobalSize( hfixed
) == 17, "wrong size %lu\n", GlobalSize( hfixed
));
1652 hmoveable
= GlobalAlloc( GMEM_MOVEABLE
, 23 );
1653 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1654 ok( GlobalSize( hmoveable
) == 23, "wrong size %lu\n", GlobalSize( hmoveable
));
1656 empty_fixed
= GlobalAlloc( GMEM_FIXED
, 0 );
1657 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1659 empty_moveable
= GlobalAlloc( GMEM_MOVEABLE
, 0 );
1660 /* discarded handles can't be GlobalLock'ed */
1661 ok( is_freed( empty_moveable
), "expected free mem %p\n", empty_moveable
);
1663 r
= OpenClipboard( hwnd
);
1664 ok( r
, "gle %d\n", GetLastError() );
1665 r
= EmptyClipboard();
1666 ok( r
, "gle %d\n", GetLastError() );
1668 h
= SetClipboardData( CF_TEXT
, htext
);
1669 ok( h
== htext
, "got %p\n", h
);
1670 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1671 h
= SetClipboardData( format_id
, htext2
);
1672 ok( h
== htext2
, "got %p\n", h
);
1673 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1674 bitmap_temp
= CreateBitmap( 10, 10, 1, 1, NULL
);
1675 h
= SetClipboardData( CF_BITMAP
, bitmap_temp
);
1676 ok( h
== bitmap_temp
, "got %p\n", h
);
1677 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1678 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1679 ok( h
== bitmap
, "got %p\n", h
);
1680 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1681 ok( !GetObjectType( bitmap_temp
), "expected free object %p\n", bitmap_temp
);
1682 h
= SetClipboardData( CF_DSPBITMAP
, bitmap2
);
1683 ok( h
== bitmap2
, "got %p\n", h
);
1684 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1685 h
= SetClipboardData( CF_PALETTE
, palette
);
1686 ok( h
== palette
, "got %p\n", h
);
1687 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1688 h
= SetClipboardData( CF_GDIOBJFIRST
+ 3, htext3
);
1689 ok( h
== htext3
, "got %p\n", h
);
1690 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1691 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, htext5
);
1692 ok( h
== htext5
, "got %p\n", h
);
1693 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1694 h
= SetClipboardData( format_id2
, empty_moveable
);
1695 ok( !h
, "got %p\n", h
);
1696 GlobalFree( empty_moveable
);
1698 if (0) /* crashes on vista64 */
1700 ptr
= HeapAlloc( GetProcessHeap(), 0, 0 );
1701 h
= SetClipboardData( format_id2
, ptr
);
1702 ok( !h
, "got %p\n", h
);
1703 HeapFree( GetProcessHeap(), 0, ptr
);
1706 h
= SetClipboardData( format_id2
, empty_fixed
);
1707 ok( h
== empty_fixed
, "got %p\n", h
);
1708 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1709 h
= SetClipboardData( 0xdeadbeef, hfixed2
);
1710 ok( h
== hfixed2
, "got %p\n", h
);
1711 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1712 h
= SetClipboardData( 0xdeadbabe, hmoveable
);
1713 ok( h
== hmoveable
, "got %p\n", h
);
1714 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1716 ptr
= HeapAlloc( GetProcessHeap(), 0, 37 );
1717 h
= SetClipboardData( 0xdeadfade, ptr
);
1718 ok( h
== ptr
|| !h
, "got %p\n", h
);
1719 if (!h
) /* heap blocks are rejected on >= win8 */
1721 HeapFree( GetProcessHeap(), 0, ptr
);
1725 data
= GetClipboardData( CF_TEXT
);
1726 ok( data
== htext
, "wrong data %p\n", data
);
1727 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1729 data
= GetClipboardData( format_id
);
1730 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1731 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1733 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1734 ok( data
== htext3
, "wrong data %p\n", data
);
1735 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1737 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1738 ok( data
== htext5
, "wrong data %p\n", data
);
1739 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1741 data
= GetClipboardData( format_id2
);
1742 ok( data
== empty_fixed
, "wrong data %p\n", data
);
1743 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1745 data
= GetClipboardData( 0xdeadbeef );
1746 ok( data
== hfixed2
, "wrong data %p\n", data
);
1747 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1749 data
= GetClipboardData( 0xdeadbabe );
1750 ok( data
== hmoveable
, "wrong data %p\n", data
);
1751 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1753 data
= GetClipboardData( 0xdeadfade );
1754 ok( data
== ptr
, "wrong data %p\n", data
);
1756 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, htext4
);
1757 ok( h
== htext4
, "got %p\n", h
);
1758 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1759 ok( is_freed( htext5
), "expected freed mem %p\n", htext5
);
1761 h
= SetClipboardData( 0xdeadbeef, hfixed
);
1762 ok( h
== hfixed
, "got %p\n", h
);
1763 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1765 /* testing if hfixed2 is freed triggers an exception on Win64 */
1766 ok( is_freed( hfixed2
) || broken( !is_freed( hfixed2
)) /* < Vista */, "expected freed mem %p\n", hfixed2
);
1769 r
= CloseClipboard();
1770 ok( r
, "gle %d\n", GetLastError() );
1772 /* data handles are still valid */
1773 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1774 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext2
);
1775 ok( is_moveable( htext3
), "expected moveable mem %p\n", htext3
);
1776 ok( is_moveable( htext4
), "expected moveable mem %p\n", htext4
);
1777 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1778 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1779 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1780 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1781 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1782 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1784 r
= OpenClipboard( hwnd
);
1785 ok( r
, "gle %d\n", GetLastError() );
1787 /* and now they are freed, unless we are the owner */
1790 ok( is_freed( htext
), "expected freed mem %p\n", htext
);
1791 ok( is_freed( htext2
), "expected freed mem %p\n", htext2
);
1792 ok( is_freed( htext3
), "expected freed mem %p\n", htext3
);
1793 ok( is_freed( htext4
), "expected freed mem %p\n", htext4
);
1794 ok( is_freed( hmoveable
), "expected freed mem %p\n", hmoveable
);
1796 data
= GetClipboardData( CF_TEXT
);
1797 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1799 data
= GetClipboardData( format_id
);
1800 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1802 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1803 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1805 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1806 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1808 data
= GetClipboardData( format_id2
);
1809 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1810 ok( GlobalSize( data
) == 1, "wrong size %lu\n", GlobalSize( data
));
1812 data
= GetClipboardData( 0xdeadbeef );
1813 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1814 ok( GlobalSize( data
) == 17, "wrong size %lu\n", GlobalSize( data
));
1816 data
= GetClipboardData( 0xdeadbabe );
1817 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1818 ok( GlobalSize( data
) == 23, "wrong size %lu\n", GlobalSize( data
));
1820 data
= GetClipboardData( 0xdeadfade );
1821 ok( is_fixed( data
) || !ptr
, "expected fixed mem %p\n", data
);
1822 if (ptr
) ok( GlobalSize( data
) == 37, "wrong size %lu\n", GlobalSize( data
));
1826 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1827 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext2
);
1828 ok( is_moveable( htext3
), "expected moveable mem %p\n", htext3
);
1829 ok( is_moveable( htext4
), "expected moveable mem %p\n", htext4
);
1830 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1832 data
= GetClipboardData( CF_TEXT
);
1833 ok( data
== htext
, "wrong data %p\n", data
);
1835 data
= GetClipboardData( format_id
);
1836 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1838 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1839 ok( data
== htext3
, "wrong data %p\n", data
);
1841 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1842 ok( data
== htext4
, "wrong data %p\n", data
);
1844 data
= GetClipboardData( format_id2
);
1845 ok( data
== empty_fixed
, "wrong data %p\n", data
);
1847 data
= GetClipboardData( 0xdeadbeef );
1848 ok( data
== hfixed
, "wrong data %p\n", data
);
1850 data
= GetClipboardData( 0xdeadbabe );
1851 ok( data
== hmoveable
, "wrong data %p\n", data
);
1853 data
= GetClipboardData( 0xdeadfade );
1854 ok( data
== ptr
, "wrong data %p\n", data
);
1857 data
= GetClipboardData( CF_OEMTEXT
);
1858 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1859 data
= GetClipboardData( CF_UNICODETEXT
);
1860 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1861 data
= GetClipboardData( CF_LOCALE
);
1862 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1863 data
= GetClipboardData( CF_BITMAP
);
1864 ok( data
== bitmap
, "expected bitmap %p\n", data
);
1865 data
= GetClipboardData( CF_DSPBITMAP
);
1866 ok( data
== bitmap2
, "expected bitmap %p\n", data
);
1867 data
= GetClipboardData( CF_PALETTE
);
1868 ok( data
== palette
, "expected palette %p\n", data
);
1869 data
= GetClipboardData( CF_DIB
);
1870 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1871 data
= GetClipboardData( CF_DIBV5
);
1872 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1874 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1875 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1876 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1877 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1878 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1880 r
= EmptyClipboard();
1881 ok( r
, "gle %d\n", GetLastError() );
1883 /* w2003, w2008 don't seem to free the data here */
1884 ok( is_freed( htext
) || broken( !is_freed( htext
)), "expected freed mem %p\n", htext
);
1885 ok( is_freed( htext2
) || broken( !is_freed( htext2
)), "expected freed mem %p\n", htext2
);
1886 ok( is_freed( htext3
) || broken( !is_freed( htext3
)), "expected freed mem %p\n", htext3
);
1887 ok( is_freed( htext4
) || broken( !is_freed( htext4
)), "expected freed mem %p\n", htext4
);
1888 ok( is_freed( hmoveable
) || broken( !is_freed( hmoveable
)), "expected freed mem %p\n", hmoveable
);
1889 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1890 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1891 ok( !GetObjectType( bitmap
), "expected freed handle %p\n", bitmap
);
1892 ok( !GetObjectType( bitmap2
), "expected freed handle %p\n", bitmap2
);
1893 ok( !GetObjectType( palette
), "expected freed handle %p\n", palette
);
1895 r
= CloseClipboard();
1896 ok( r
, "gle %d\n", GetLastError() );
1899 static DWORD WINAPI
test_handles_thread( void *arg
)
1901 trace( "running from different thread\n" );
1902 test_handles( (HWND
)arg
);
1906 static DWORD WINAPI
test_handles_thread2( void *arg
)
1912 r
= OpenClipboard( 0 );
1913 ok( r
, "gle %d\n", GetLastError() );
1914 h
= GetClipboardData( CF_TEXT
);
1915 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1916 ptr
= GlobalLock( h
);
1917 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1919 h
= GetClipboardData( format_id
);
1920 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1921 ptr
= GlobalLock( h
);
1922 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1924 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1925 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1926 ptr
= GlobalLock( h
);
1927 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1929 trace( "gdiobj %p\n", h
);
1930 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1931 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1932 ptr
= GlobalLock( h
);
1933 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1935 trace( "private %p\n", h
);
1936 h
= GetClipboardData( CF_BITMAP
);
1937 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1938 ok( h
== bitmap
, "different bitmap %p / %p\n", h
, bitmap
);
1939 trace( "bitmap %p\n", h
);
1940 h
= GetClipboardData( CF_DSPBITMAP
);
1941 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1942 ok( h
== bitmap2
, "different bitmap %p / %p\n", h
, bitmap2
);
1943 trace( "bitmap2 %p\n", h
);
1944 h
= GetClipboardData( CF_PALETTE
);
1945 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1946 ok( h
== palette
, "different palette %p / %p\n", h
, palette
);
1947 trace( "palette %p\n", h
);
1948 h
= GetClipboardData( CF_DIB
);
1949 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1950 h
= GetClipboardData( CF_DIBV5
);
1951 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1952 r
= CloseClipboard();
1953 ok( r
, "gle %d\n", GetLastError() );
1957 static void test_handles_process( const char *str
)
1966 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
1967 r
= OpenClipboard( 0 );
1968 ok( r
, "gle %d\n", GetLastError() );
1969 h
= GetClipboardData( CF_TEXT
);
1970 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1971 ptr
= GlobalLock( h
);
1972 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1974 h
= GetClipboardData( format_id
);
1975 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1976 ptr
= GlobalLock( h
);
1977 if (ptr
) ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1979 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1980 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1981 ptr
= GlobalLock( h
);
1982 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1984 trace( "gdiobj %p\n", h
);
1985 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1986 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1987 ptr
= GlobalLock( h
);
1988 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1990 trace( "private %p\n", h
);
1991 h
= GetClipboardData( CF_BITMAP
);
1992 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1993 ok( GetObjectW( h
, sizeof(bm
), &bm
) == sizeof(bm
), "GetObject %p failed\n", h
);
1994 ok( bm
.bmWidth
== 13 && bm
.bmHeight
== 17, "wrong bitmap %ux%u\n", bm
.bmWidth
, bm
.bmHeight
);
1995 trace( "bitmap %p\n", h
);
1996 h
= GetClipboardData( CF_DSPBITMAP
);
1997 ok( !GetObjectType( h
), "expected invalid object %p\n", h
);
1998 trace( "bitmap2 %p\n", h
);
1999 h
= GetClipboardData( CF_PALETTE
);
2000 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
2001 ok( GetPaletteEntries( h
, 0, 1, &entry
) == 1, "GetPaletteEntries %p failed\n", h
);
2002 ok( entry
.peRed
== 0x12 && entry
.peGreen
== 0x34 && entry
.peBlue
== 0x56,
2003 "wrong color %02x,%02x,%02x\n", entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
2004 trace( "palette %p\n", h
);
2005 h
= GetClipboardData( CF_METAFILEPICT
);
2006 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2007 ok( GetObjectType( ((METAFILEPICT
*)h
)->hMF
) == OBJ_METAFILE
,
2008 "wrong object %p\n", ((METAFILEPICT
*)h
)->hMF
);
2009 trace( "metafile %p\n", h
);
2010 h
= GetClipboardData( CF_DSPMETAFILEPICT
);
2011 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2012 ok( GetObjectType( ((METAFILEPICT
*)h
)->hMF
) == OBJ_METAFILE
,
2013 "wrong object %p\n", ((METAFILEPICT
*)h
)->hMF
);
2014 trace( "metafile2 %p\n", h
);
2015 h
= GetClipboardData( CF_ENHMETAFILE
);
2016 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2017 ok( GetEnhMetaFileBits( h
, sizeof(buffer
), buffer
) > sizeof(ENHMETAHEADER
),
2018 "GetEnhMetaFileBits failed on %p\n", h
);
2019 ok( ((ENHMETAHEADER
*)buffer
)->nRecords
== 3,
2020 "wrong records %u\n", ((ENHMETAHEADER
*)buffer
)->nRecords
);
2021 trace( "enhmetafile %p\n", h
);
2022 h
= GetClipboardData( CF_DSPENHMETAFILE
);
2023 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2024 ok( GetEnhMetaFileBits( h
, sizeof(buffer
), buffer
) > sizeof(ENHMETAHEADER
),
2025 "GetEnhMetaFileBits failed on %p\n", h
);
2026 ok( ((ENHMETAHEADER
*)buffer
)->nRecords
== 3,
2027 "wrong records %u\n", ((ENHMETAHEADER
*)buffer
)->nRecords
);
2028 trace( "enhmetafile2 %p\n", h
);
2029 h
= GetClipboardData( CF_DIB
);
2030 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2031 h
= GetClipboardData( CF_DIBV5
);
2032 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2033 r
= CloseClipboard();
2034 ok( r
, "gle %d\n", GetLastError() );
2037 static void test_handles_process_open( const char *str
)
2039 HANDLE h
, text
= GlobalAlloc( GMEM_DDESHARE
|GMEM_MOVEABLE
, strlen(str
) + 1 );
2040 char *ptr
= GlobalLock( text
);
2043 GlobalUnlock( text
);
2045 /* clipboard already open by parent process */
2046 h
= SetClipboardData( CF_TEXT
, text
);
2047 ok( h
== text
, "wrong mem %p / %p\n", h
, text
);
2048 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2051 static void test_handles_process_dib( const char *str
)
2056 r
= OpenClipboard( 0 );
2057 ok( r
, "gle %d\n", GetLastError() );
2058 h
= GetClipboardData( CF_BITMAP
);
2059 ok( !GetObjectType( h
), "expected invalid object %p\n", h
);
2060 trace( "dibsection %p\n", h
);
2061 r
= CloseClipboard();
2062 ok( r
, "gle %d\n", GetLastError() );
2065 static void test_data_handles(void)
2070 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
2074 ok( hwnd
!= 0, "window creation failed\n" );
2075 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
2077 test_handles( GetDesktopWindow() );
2078 test_handles( hwnd
);
2079 run_thread( test_handles_thread
, hwnd
, __LINE__
);
2081 bitmap
= CreateBitmap( 13, 17, 1, 1, NULL
);
2082 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
2083 palette
= CreatePalette( &logpalette
);
2085 r
= OpenClipboard( hwnd
);
2086 ok( r
, "gle %d\n", GetLastError() );
2087 r
= EmptyClipboard();
2088 ok( r
, "gle %d\n", GetLastError() );
2089 h
= SetClipboardData( CF_TEXT
, create_textA() );
2090 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2091 h
= SetClipboardData( format_id
, create_textA() );
2092 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2093 h
= SetClipboardData( CF_BITMAP
, bitmap
);
2094 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
2095 h
= SetClipboardData( CF_DSPBITMAP
, bitmap2
);
2096 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
2097 h
= SetClipboardData( CF_PALETTE
, palette
);
2098 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
2099 h
= SetClipboardData( CF_METAFILEPICT
, create_metafile() );
2100 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2101 trace( "metafile %p\n", h
);
2102 h
= SetClipboardData( CF_DSPMETAFILEPICT
, create_metafile() );
2103 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2104 trace( "metafile2 %p\n", h
);
2105 h
= SetClipboardData( CF_ENHMETAFILE
, create_emf() );
2106 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2107 trace( "enhmetafile %p\n", h
);
2108 h
= SetClipboardData( CF_DSPENHMETAFILE
, create_emf() );
2109 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
2110 trace( "enhmetafile2 %p\n", h
);
2111 h
= SetClipboardData( CF_GDIOBJFIRST
+ 3, create_textA() );
2112 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2113 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, create_textA() );
2114 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2115 r
= CloseClipboard();
2116 ok( r
, "gle %d\n", GetLastError() );
2118 run_thread( test_handles_thread2
, 0, __LINE__
);
2119 run_process( "handles test" );
2121 r
= OpenClipboard( hwnd
);
2122 ok( r
, "gle %d\n", GetLastError() );
2123 h
= GetClipboardData( CF_TEXT
);
2124 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2125 h
= GetClipboardData( format_id
);
2126 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2127 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
2128 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2129 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
2130 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2132 r
= EmptyClipboard();
2133 ok( r
, "gle %d\n", GetLastError() );
2134 text
= create_textA();
2135 h
= SetClipboardData( CF_TEXT
, text
);
2136 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
2138 run_process( "handles_open foobar" );
2140 ok( is_moveable( text
), "expected moveable mem %p\n", text
);
2141 h
= GetClipboardData( CF_TEXT
);
2142 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
2143 ok( is_moveable( text
), "expected moveable mem %p\n", text
);
2144 ptr
= GlobalLock( h
);
2145 ok( !strcmp( ptr
, "foobar" ), "wrong data '%.8s'\n", ptr
);
2148 r
= EmptyClipboard();
2149 ok( r
, "gle %d\n", GetLastError() );
2150 ok( is_fixed( h
), "expected free mem %p\n", h
);
2151 ok( is_freed( text
) || broken( is_moveable(text
) ), /* w2003, w2008 */
2152 "expected free mem %p\n", text
);
2153 r
= CloseClipboard();
2154 ok( r
, "gle %d\n", GetLastError() );
2156 /* test CF_BITMAP with a DIB section */
2157 memset( &bmi
, 0, sizeof(bmi
) );
2158 bmi
.bmiHeader
.biSize
= sizeof( bmi
.bmiHeader
);
2159 bmi
.bmiHeader
.biWidth
= 29;
2160 bmi
.bmiHeader
.biHeight
= 13;
2161 bmi
.bmiHeader
.biPlanes
= 1;
2162 bmi
.bmiHeader
.biBitCount
= 32;
2163 bitmap
= CreateDIBSection( 0, &bmi
, DIB_RGB_COLORS
, &bits
, 0, 0 );
2165 r
= OpenClipboard( hwnd
);
2166 ok( r
, "gle %d\n", GetLastError() );
2167 r
= EmptyClipboard();
2168 ok( r
, "gle %d\n", GetLastError() );
2169 h
= SetClipboardData( CF_BITMAP
, bitmap
);
2170 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
2171 trace( "dibsection %p\n", h
);
2172 r
= CloseClipboard();
2173 ok( r
, "gle %d\n", GetLastError() );
2175 run_process( "handles_dib dummy" );
2177 r
= OpenClipboard( hwnd
);
2178 ok( r
, "gle %d\n", GetLastError() );
2179 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
2180 r
= EmptyClipboard();
2181 ok( r
, "gle %d\n", GetLastError() );
2182 ok( !GetObjectType( bitmap
), "expected deleted %p\n", bitmap
);
2183 r
= CloseClipboard();
2184 ok( r
, "gle %d\n", GetLastError() );
2186 DestroyWindow( hwnd
);
2189 static void test_GetUpdatedClipboardFormats(void)
2192 UINT count
, formats
[256];
2194 if (!pGetUpdatedClipboardFormats
)
2196 win_skip( "GetUpdatedClipboardFormats not supported\n" );
2201 r
= pGetUpdatedClipboardFormats( NULL
, 0, &count
);
2202 ok( r
, "gle %d\n", GetLastError() );
2203 ok( !count
, "wrong count %u\n", count
);
2206 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2207 ok( r
, "gle %d\n", GetLastError() );
2208 ok( !count
, "wrong count %u\n", count
);
2210 SetLastError( 0xdeadbeef );
2211 r
= pGetUpdatedClipboardFormats( formats
, 256, NULL
);
2212 ok( !r
, "succeeded\n" );
2213 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2216 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2217 ok( r
, "gle %d\n", GetLastError() );
2218 ok( !count
, "wrong count %u\n", count
);
2220 r
= OpenClipboard( 0 );
2221 ok( r
, "gle %d\n", GetLastError() );
2222 r
= EmptyClipboard();
2223 ok( r
, "gle %d\n", GetLastError() );
2226 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2227 ok( r
, "gle %d\n", GetLastError() );
2228 ok( !count
, "wrong count %u\n", count
);
2230 SetClipboardData( CF_UNICODETEXT
, 0 );
2233 memset( formats
, 0xcc, sizeof(formats
) );
2234 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2235 ok( r
, "gle %d\n", GetLastError() );
2236 ok( count
== 1, "wrong count %u\n", count
);
2237 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2238 ok( formats
[1] == 0xcccccccc, "wrong format %u\n", formats
[1] );
2240 SetClipboardData( CF_TEXT
, 0 );
2242 memset( formats
, 0xcc, sizeof(formats
) );
2243 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2244 ok( r
, "gle %d\n", GetLastError() );
2245 ok( count
== 2, "wrong count %u\n", count
);
2246 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2247 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
2248 ok( formats
[2] == 0xcccccccc, "wrong format %u\n", formats
[2] );
2250 SetLastError( 0xdeadbeef );
2252 r
= pGetUpdatedClipboardFormats( formats
, 0, &count
);
2253 ok( !r
, "succeeded\n" );
2254 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2255 ok( count
== 2, "wrong count %u\n", count
);
2257 SetLastError( 0xdeadbeef );
2259 r
= pGetUpdatedClipboardFormats( formats
, 1, &count
);
2260 ok( !r
, "succeeded\n" );
2261 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2262 ok( count
== 2, "wrong count %u\n", count
);
2264 r
= CloseClipboard();
2265 ok( r
, "gle %d\n", GetLastError() );
2268 memset( formats
, 0xcc, sizeof(formats
) );
2269 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
2270 ok( r
, "gle %d\n", GetLastError() );
2271 ok( count
== 4, "wrong count %u\n", count
);
2272 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2273 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
2274 ok( formats
[2] == CF_LOCALE
, "wrong format %u\n", formats
[2] );
2275 ok( formats
[3] == CF_OEMTEXT
, "wrong format %u\n", formats
[3] );
2276 ok( formats
[4] == 0xcccccccc, "wrong format %u\n", formats
[4] );
2279 memset( formats
, 0xcc, sizeof(formats
) );
2280 r
= pGetUpdatedClipboardFormats( formats
, 2, &count
);
2281 ok( !r
, "gle %d\n", GetLastError() );
2282 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2283 ok( count
== 4, "wrong count %u\n", count
);
2284 ok( formats
[0] == 0xcccccccc, "wrong format %u\n", formats
[0] );
2287 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2288 ok( !r
, "gle %d\n", GetLastError() );
2289 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2290 ok( count
== 4, "wrong count %u\n", count
);
2293 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2294 ok( !r
, "gle %d\n", GetLastError() );
2295 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2296 ok( count
== 4, "wrong count %u\n", count
);
2306 { "foo", {0}, 3 }, /* 0 */
2308 { "foo\0bar", {0}, 7 },
2309 { "foo\0bar", {0}, 8 },
2310 { "", {'f','o','o'}, 3 * sizeof(WCHAR
) },
2311 { "", {'f','o','o',0}, 4 * sizeof(WCHAR
) }, /* 5 */
2312 { "", {'f','o','o',0,'b','a','r'}, 7 * sizeof(WCHAR
) },
2313 { "", {'f','o','o',0,'b','a','r',0}, 8 * sizeof(WCHAR
) },
2314 { "", {'f','o','o'}, 1 },
2315 { "", {'f','o','o'}, 2 },
2316 { "", {'f','o','o'}, 5 }, /* 10 */
2317 { "", {'f','o','o',0}, 7 },
2318 { "", {'f','o','o',0}, 9 },
2321 static void test_string_data(void)
2330 for (i
= 0; i
< sizeof(test_data
) / sizeof(test_data
[0]); i
++)
2332 /* 1-byte Unicode strings crash on Win64 */
2334 if (!test_data
[i
].strA
[0] && test_data
[i
].len
< sizeof(WCHAR
)) continue;
2336 r
= OpenClipboard( 0 );
2337 ok( r
, "gle %d\n", GetLastError() );
2338 r
= EmptyClipboard();
2339 ok( r
, "gle %d\n", GetLastError() );
2340 data
= GlobalAlloc( GMEM_FIXED
, test_data
[i
].len
);
2341 if (test_data
[i
].strA
[0])
2343 memcpy( data
, test_data
[i
].strA
, test_data
[i
].len
);
2344 SetClipboardData( CF_TEXT
, data
);
2345 memcpy( bufferA
, test_data
[i
].strA
, test_data
[i
].len
);
2346 bufferA
[test_data
[i
].len
- 1] = 0;
2347 ok( !memcmp( data
, bufferA
, test_data
[i
].len
),
2348 "%u: wrong data %.*s\n", i
, test_data
[i
].len
, (char *)data
);
2352 memcpy( data
, test_data
[i
].strW
, test_data
[i
].len
);
2353 SetClipboardData( CF_UNICODETEXT
, data
);
2354 memcpy( bufferW
, test_data
[i
].strW
, test_data
[i
].len
);
2355 bufferW
[(test_data
[i
].len
+ 1) / sizeof(WCHAR
) - 1] = 0;
2356 ok( !memcmp( data
, bufferW
, test_data
[i
].len
),
2357 "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, (test_data
[i
].len
+ 1) / sizeof(WCHAR
) ));
2359 r
= CloseClipboard();
2360 ok( r
, "gle %d\n", GetLastError() );
2361 sprintf( cmd
, "string_data %u", i
);
2366 static void test_string_data_process( int i
)
2374 r
= OpenClipboard( 0 );
2375 ok( r
, "gle %d\n", GetLastError() );
2376 if (test_data
[i
].strA
[0])
2378 data
= GetClipboardData( CF_TEXT
);
2379 ok( data
!= 0, "%u: could not get data\n", i
);
2380 len
= GlobalSize( data
);
2381 ok( len
== test_data
[i
].len
, "%u: wrong size %u / %u\n", i
, len
, test_data
[i
].len
);
2382 memcpy( bufferA
, test_data
[i
].strA
, test_data
[i
].len
);
2383 bufferA
[test_data
[i
].len
- 1] = 0;
2384 ok( !memcmp( data
, bufferA
, len
), "%u: wrong data %.*s\n", i
, len
, (char *)data
);
2385 data
= GetClipboardData( CF_UNICODETEXT
);
2386 ok( data
!= 0, "%u: could not get data\n", i
);
2387 len
= GlobalSize( data
);
2388 len2
= MultiByteToWideChar( CP_ACP
, 0, bufferA
, test_data
[i
].len
, bufferW
, 12 );
2389 ok( len
== len2
* sizeof(WCHAR
), "%u: wrong size %u / %u\n", i
, len
, len2
);
2390 ok( !memcmp( data
, bufferW
, len
), "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, len2
));
2394 data
= GetClipboardData( CF_UNICODETEXT
);
2395 ok( data
!= 0, "%u: could not get data\n", i
);
2396 len
= GlobalSize( data
);
2397 ok( len
== test_data
[i
].len
, "%u: wrong size %u / %u\n", i
, len
, test_data
[i
].len
);
2398 memcpy( bufferW
, test_data
[i
].strW
, test_data
[i
].len
);
2399 bufferW
[(test_data
[i
].len
+ 1) / sizeof(WCHAR
) - 1] = 0;
2400 ok( !memcmp( data
, bufferW
, len
),
2401 "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, (len
+ 1) / sizeof(WCHAR
) ));
2402 data
= GetClipboardData( CF_TEXT
);
2403 if (test_data
[i
].len
>= sizeof(WCHAR
))
2405 ok( data
!= 0, "%u: could not get data\n", i
);
2406 len
= GlobalSize( data
);
2407 len2
= WideCharToMultiByte( CP_ACP
, 0, bufferW
, test_data
[i
].len
/ sizeof(WCHAR
),
2408 bufferA
, 12, NULL
, NULL
);
2409 bufferA
[len2
- 1] = 0;
2410 ok( len
== len2
, "%u: wrong size %u / %u\n", i
, len
, len2
);
2411 ok( !memcmp( data
, bufferA
, len
), "%u: wrong data %.*s\n", i
, len
, (char *)data
);
2415 ok( !data
, "%u: got data for empty string\n", i
);
2416 ok( IsClipboardFormatAvailable( CF_TEXT
), "%u: text not available\n", i
);
2419 r
= CloseClipboard();
2420 ok( r
, "gle %d\n", GetLastError() );
2423 START_TEST(clipboard
)
2426 int argc
= winetest_get_mainargs( &argv
);
2427 HMODULE mod
= GetModuleHandleA( "user32" );
2430 pAddClipboardFormatListener
= (void *)GetProcAddress( mod
, "AddClipboardFormatListener" );
2431 pRemoveClipboardFormatListener
= (void *)GetProcAddress( mod
, "RemoveClipboardFormatListener" );
2432 pGetUpdatedClipboardFormats
= (void *)GetProcAddress( mod
, "GetUpdatedClipboardFormats" );
2434 if (argc
== 4 && !strcmp( argv
[2], "set_clipboard_data" ))
2436 set_clipboard_data_process( atoi( argv
[3] ));
2439 if (argc
== 4 && !strcmp( argv
[2], "grab_clipboard" ))
2441 grab_clipboard_process( atoi( argv
[3] ));
2444 if (argc
== 4 && !strcmp( argv
[2], "handles" ))
2446 test_handles_process( argv
[3] );
2449 if (argc
== 4 && !strcmp( argv
[2], "handles_open" ))
2451 test_handles_process_open( argv
[3] );
2454 if (argc
== 4 && !strcmp( argv
[2], "handles_dib" ))
2456 test_handles_process_dib( argv
[3] );
2459 if (argc
== 4 && !strcmp( argv
[2], "string_data" ))
2461 test_string_data_process( atoi( argv
[3] ));
2464 if (argc
== 3 && !strcmp( argv
[2], "get_clipboard_data" ))
2466 get_clipboard_data_process( );
2470 test_RegisterClipboardFormatA();
2471 test_ClipboardOwner();
2474 test_data_handles();
2475 test_GetUpdatedClipboardFormats();