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"
30 #define WM_CLIPBOARDUPDATE 0x031D
33 static BOOL (WINAPI
*pAddClipboardFormatListener
)(HWND hwnd
);
34 static BOOL (WINAPI
*pRemoveClipboardFormatListener
)(HWND hwnd
);
35 static BOOL (WINAPI
*pGetUpdatedClipboardFormats
)( UINT
*formats
, UINT count
, UINT
*out_count
);
37 static int thread_from_line
;
40 static DWORD WINAPI
open_clipboard_thread(LPVOID arg
)
43 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
47 static DWORD WINAPI
empty_clipboard_thread(LPVOID arg
)
49 SetLastError( 0xdeadbeef );
50 ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line
);
51 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
52 thread_from_line
, GetLastError());
56 static DWORD WINAPI
open_and_empty_clipboard_thread(LPVOID arg
)
59 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
60 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
64 static DWORD WINAPI
open_and_empty_clipboard_win_thread(LPVOID arg
)
66 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
67 ok(OpenClipboard(hwnd
), "%u: OpenClipboard failed\n", thread_from_line
);
68 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
72 static DWORD WINAPI
set_clipboard_data_thread(LPVOID arg
)
77 SetLastError( 0xdeadbeef );
78 if (GetClipboardOwner() == hwnd
)
80 SetClipboardData( CF_WAVE
, 0 );
81 ok( IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData failed\n", thread_from_line
);
82 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
83 ok( ret
!= 0, "%u: SetClipboardData failed err %u\n", thread_from_line
, GetLastError() );
84 SetLastError( 0xdeadbeef );
85 ret
= GetClipboardData( CF_WAVE
);
86 ok( !ret
, "%u: GetClipboardData succeeded\n", thread_from_line
);
87 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
88 thread_from_line
, GetLastError());
92 SetClipboardData( CF_WAVE
, 0 );
93 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
94 thread_from_line
, GetLastError());
95 ok( !IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData succeeded\n", thread_from_line
);
96 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
97 ok( !ret
, "%u: SetClipboardData succeeded\n", thread_from_line
);
98 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
99 thread_from_line
, GetLastError());
104 static void set_clipboard_data_process( int arg
)
108 SetLastError( 0xdeadbeef );
111 ok( IsClipboardFormatAvailable( CF_WAVE
), "process %u: CF_WAVE not available\n", arg
);
112 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
113 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
117 SetClipboardData( CF_WAVE
, 0 );
118 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
119 arg
, GetLastError());
120 ok( !IsClipboardFormatAvailable( CF_WAVE
), "process %u: SetClipboardData succeeded\n", arg
);
121 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
122 ok( !ret
, "process %u: SetClipboardData succeeded\n", arg
);
123 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "process %u: wrong error %u\n",
124 arg
, GetLastError());
128 static void grab_clipboard_process( int arg
)
132 SetLastError( 0xdeadbeef );
133 ret
= OpenClipboard( 0 );
134 ok( ret
, "OpenClipboard failed\n" );
135 ret
= EmptyClipboard();
136 ok( ret
, "EmptyClipboard failed\n" );
139 HANDLE ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
140 ok( ret
!= 0, "process %u: SetClipboardData failed err %u\n", arg
, GetLastError() );
144 static void run_thread( LPTHREAD_START_ROUTINE func
, void *arg
, int line
)
149 thread_from_line
= line
;
150 thread
= CreateThread(NULL
, 0, func
, arg
, 0, NULL
);
151 ok(thread
!= NULL
, "%u: CreateThread failed with error %d\n", line
, GetLastError());
154 ret
= MsgWaitForMultipleObjectsEx( 1, &thread
, 1000, QS_ALLINPUT
, 0 );
155 if (ret
== WAIT_OBJECT_0
+ 1)
158 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
162 ok(ret
== WAIT_OBJECT_0
, "%u: expected WAIT_OBJECT_0, got %u\n", line
, ret
);
166 static void run_process( const char *args
)
169 PROCESS_INFORMATION info
;
170 STARTUPINFOA startup
;
172 sprintf( cmd
, "%s clipboard %s", argv0
, args
);
173 memset( &startup
, 0, sizeof(startup
) );
174 startup
.cb
= sizeof(startup
);
175 ok( CreateProcessA( NULL
, cmd
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &startup
, &info
),
176 "CreateProcess %s failed\n", cmd
);
178 winetest_wait_child_process( info
.hProcess
);
179 CloseHandle( info
.hProcess
);
180 CloseHandle( info
.hThread
);
183 static WNDPROC old_proc
;
184 static LRESULT CALLBACK
winproc_wrapper( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
186 static int wm_renderallformats
;
187 static int wm_drawclipboard
;
189 DWORD msg_flags
= InSendMessageEx( NULL
);
191 if (!seqno
) seqno
= GetClipboardSequenceNumber();
193 trace( "%p msg %04x\n", hwnd
, msg
);
194 if (!wm_renderallformats
)
196 ok( GetClipboardOwner() == hwnd
, "%04x: wrong owner %p/%p\n", msg
, GetClipboardOwner(), hwnd
);
197 ok( seqno
== GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg
);
201 ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg
, GetClipboardOwner() );
202 ok( seqno
+ 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg
);
204 ok( GetClipboardViewer() == hwnd
, "%04x: wrong viewer %p/%p\n", msg
, GetClipboardViewer(), hwnd
);
205 ok( GetOpenClipboardWindow() == hwnd
, "%04x: wrong open win %p/%p\n",
206 msg
, GetOpenClipboardWindow(), hwnd
);
211 ok( wm_renderallformats
, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
212 ok( wm_drawclipboard
, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
214 case WM_DRAWCLIPBOARD
:
215 ok( msg_flags
== ISMEX_NOSEND
, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
218 case WM_RENDERALLFORMATS
:
219 ok( msg_flags
== ISMEX_NOSEND
, "WM_RENDERALLFORMATS wrong flags %x\n", msg_flags
);
220 wm_renderallformats
++;
223 return old_proc( hwnd
, msg
, wp
, lp
);
226 static void test_ClipboardOwner(void)
231 SetLastError(0xdeadbeef);
232 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
233 "could not perform clipboard test: clipboard already owned\n");
235 hWnd1
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
236 0, 0, 10, 10, 0, 0, 0, NULL
);
237 ok(hWnd1
!= 0, "CreateWindowExA error %d\n", GetLastError());
238 trace("hWnd1 = %p\n", hWnd1
);
240 hWnd2
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
241 0, 0, 10, 10, 0, 0, 0, NULL
);
242 ok(hWnd2
!= 0, "CreateWindowExA error %d\n", GetLastError());
243 trace("hWnd2 = %p\n", hWnd2
);
245 SetLastError(0xdeadbeef);
246 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
247 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
248 "wrong error %u\n", GetLastError());
250 ok(OpenClipboard(0), "OpenClipboard failed\n");
251 ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
252 ok(!OpenClipboard(hWnd1
), "OpenClipboard should fail since clipboard already opened\n");
253 ok(OpenClipboard(0), "OpenClipboard again failed\n");
254 ret
= CloseClipboard();
255 ok( ret
, "CloseClipboard error %d\n", GetLastError());
257 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
258 run_thread( open_clipboard_thread
, hWnd1
, __LINE__
);
259 run_thread( empty_clipboard_thread
, 0, __LINE__
);
260 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
261 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
262 ok( !GetClipboardData( CF_WAVE
), "CF_WAVE data available\n" );
263 run_process( "set_clipboard_data 0" );
264 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
265 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
267 SetLastError(0xdeadbeef);
268 ret
= OpenClipboard(hWnd2
);
269 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
270 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
272 SetLastError(0xdeadbeef);
273 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
274 ret
= EmptyClipboard();
275 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
276 ok(GetClipboardOwner() == hWnd1
, "clipboard should be owned by %p, not by %p\n", hWnd1
, GetClipboardOwner());
277 run_thread( empty_clipboard_thread
, 0, __LINE__
);
278 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
279 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
280 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
281 run_process( "set_clipboard_data 1" );
283 SetLastError(0xdeadbeef);
284 ret
= OpenClipboard(hWnd2
);
285 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
286 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
288 ret
= CloseClipboard();
289 ok( ret
, "CloseClipboard error %d\n", GetLastError());
290 ok(GetClipboardOwner() == hWnd1
, "clipboard should still be owned\n");
292 /* any window will do, even from a different process */
293 ret
= OpenClipboard( GetDesktopWindow() );
294 ok( ret
, "OpenClipboard error %d\n", GetLastError());
295 ret
= EmptyClipboard();
296 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
297 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
298 GetClipboardOwner(), GetDesktopWindow() );
299 run_thread( set_clipboard_data_thread
, GetDesktopWindow(), __LINE__
);
300 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
301 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
302 run_process( "set_clipboard_data 2" );
303 ret
= CloseClipboard();
304 ok( ret
, "CloseClipboard error %d\n", GetLastError());
306 ret
= OpenClipboard( hWnd1
);
307 ok( ret
, "OpenClipboard error %d\n", GetLastError());
308 ret
= EmptyClipboard();
309 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
310 SetClipboardData( CF_WAVE
, 0 );
311 SetClipboardViewer( hWnd1
);
312 ok( GetClipboardOwner() == hWnd1
, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1
);
313 ok( GetClipboardViewer() == hWnd1
, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1
);
314 ok( GetOpenClipboardWindow() == hWnd1
, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1
);
315 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
317 old_proc
= (WNDPROC
)SetWindowLongPtrA( hWnd1
, GWLP_WNDPROC
, (LONG_PTR
)winproc_wrapper
);
318 ret
= DestroyWindow(hWnd1
);
319 ok( ret
, "DestroyWindow error %d\n", GetLastError());
320 ret
= DestroyWindow(hWnd2
);
321 ok( ret
, "DestroyWindow error %d\n", GetLastError());
322 SetLastError(0xdeadbeef);
323 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
324 ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n");
325 ok(!GetOpenClipboardWindow() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n");
326 ok( !IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE available\n" );
328 SetLastError( 0xdeadbeef );
329 ret
= CloseClipboard();
330 ok( !ret
, "CloseClipboard succeeded\n" );
331 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
333 ret
= OpenClipboard( 0 );
334 ok( ret
, "OpenClipboard error %d\n", GetLastError());
335 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
336 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
337 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
338 run_process( "set_clipboard_data 3" );
339 ret
= CloseClipboard();
340 ok( ret
, "CloseClipboard error %d\n", GetLastError());
342 run_thread( open_and_empty_clipboard_thread
, 0, __LINE__
);
343 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
344 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
346 ret
= OpenClipboard( 0 );
347 ok( ret
, "OpenClipboard error %d\n", GetLastError());
348 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
349 ok( IsClipboardFormatAvailable( CF_WAVE
), "CF_WAVE not available\n" );
350 ok( GetClipboardData( CF_WAVE
) != 0, "CF_WAVE data not available\n" );
351 run_process( "set_clipboard_data 4" );
352 ret
= EmptyClipboard();
353 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
354 ret
= CloseClipboard();
355 ok( ret
, "CloseClipboard error %d\n", GetLastError());
357 SetLastError( 0xdeadbeef );
358 ok( !SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 )),
359 "SetClipboardData succeeded\n" );
360 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
361 ok( !IsClipboardFormatAvailable( CF_WAVE
), "SetClipboardData succeeded\n" );
363 run_thread( open_and_empty_clipboard_thread
, GetDesktopWindow(), __LINE__
);
364 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
365 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n",
366 GetClipboardOwner(), GetDesktopWindow() );
368 run_thread( open_and_empty_clipboard_win_thread
, 0, __LINE__
);
369 ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
370 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
373 static void test_RegisterClipboardFormatA(void)
376 UINT format_id
, format_id2
;
382 format_id
= RegisterClipboardFormatA("my_cool_clipboard_format");
383 ok(format_id
> 0xc000 && format_id
< 0xffff, "invalid clipboard format id %04x\n", format_id
);
385 format_id2
= RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
386 ok(format_id2
== format_id
, "invalid clipboard format id %04x\n", format_id2
);
388 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
389 ok(len
== lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len
);
390 ok(!lstrcmpA(buf
, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf
);
392 len
= GetClipboardFormatNameA(format_id
, NULL
, 0);
393 ok(len
== 0, "wrong format name length %d\n", len
);
395 lstrcpyA(buf
, "foo");
396 SetLastError(0xdeadbeef);
397 len
= GetAtomNameA((ATOM
)format_id
, buf
, 256);
398 ok(len
== 0, "GetAtomNameA should fail\n");
399 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
403 lstrcpyA(buf
, "foo");
404 SetLastError(0xdeadbeef);
405 len
= GlobalGetAtomNameA((ATOM
)format_id
, buf
, 256);
406 ok(len
== 0, "GlobalGetAtomNameA should fail\n");
407 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
410 SetLastError(0xdeadbeef);
411 atom_id
= FindAtomA("my_cool_clipboard_format");
412 ok(atom_id
== 0, "FindAtomA should fail\n");
413 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
417 /* this relies on the clipboard and global atom table being different */
418 SetLastError(0xdeadbeef);
419 atom_id
= GlobalFindAtomA("my_cool_clipboard_format");
420 ok(atom_id
== 0, "GlobalFindAtomA should fail\n");
421 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
424 for (format_id
= 0; format_id
< 0x10fff; format_id
++)
426 SetLastError(0xdeadbeef);
427 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
429 if (format_id
< 0xc000 || format_id
> 0xffff)
430 ok(!len
, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len
, buf
);
431 else if (len
&& winetest_debug
> 1)
432 trace("%04x: %s\n", format_id
, len
? buf
: "");
435 ret
= OpenClipboard(0);
436 ok( ret
, "OpenClipboard error %d\n", GetLastError());
438 /* try some invalid/unregistered formats */
439 SetLastError( 0xdeadbeef );
440 handle
= SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
441 ok( !handle
, "SetClipboardData succeeded\n" );
442 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError());
443 handle
= SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
444 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
445 handle
= SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
446 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
447 handle
= SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
448 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
450 ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
451 ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
452 ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
453 ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
454 ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
455 ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
457 trace("# of formats available: %d\n", CountClipboardFormats());
460 while ((format_id
= EnumClipboardFormats(format_id
)))
462 ok(IsClipboardFormatAvailable(format_id
), "format %04x was listed as available\n", format_id
);
463 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
464 trace("%04x: %s\n", format_id
, len
? buf
: "");
467 ret
= EmptyClipboard();
468 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
469 ret
=CloseClipboard();
470 ok( ret
, "CloseClipboard error %d\n", GetLastError());
472 if (CountClipboardFormats())
474 SetLastError(0xdeadbeef);
475 ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
476 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
,
477 "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError());
480 SetLastError(0xdeadbeef);
481 ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
482 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
483 "Wrong error %u\n", GetLastError());
485 format_id
= RegisterClipboardFormatA("#1234");
486 ok(format_id
== 1234, "invalid clipboard format id %04x\n", format_id
);
489 static HGLOBAL
create_textA(void)
491 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, 10);
492 char *p
= GlobalLock(h
);
493 memcpy(p
, "test\0\0\0\0\0", 10);
498 static HGLOBAL
create_textW(void)
500 static const WCHAR testW
[] = {'t','e','s','t',0,0,0,0,0,0};
501 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, sizeof(testW
));
502 WCHAR
*p
= GlobalLock(h
);
503 memcpy(p
, testW
, sizeof(testW
));
508 static HANDLE
create_metafile(void)
510 const RECT rect
= {0, 0, 100, 100};
514 HDC hdc
= CreateMetaFileA( NULL
);
515 ExtTextOutA( hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
516 mf
= CloseMetaFile( hdc
);
517 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, sizeof(*pict
) );
518 pict
= GlobalLock( ret
);
520 pict
->xExt
= pict
->yExt
= 100;
526 static HENHMETAFILE
create_emf(void)
528 const RECT rect
= {0, 0, 100, 100};
529 HDC hdc
= CreateEnhMetaFileA(NULL
, NULL
, &rect
, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
530 ExtTextOutA(hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
531 return CloseEnhMetaFile(hdc
);
534 static HBITMAP
create_bitmap(void)
536 HDC hdc
= GetDC( 0 );
537 UINT bpp
= GetDeviceCaps( hdc
, BITSPIXEL
);
539 return CreateBitmap( 10, 10, 1, bpp
, NULL
);
542 static HBITMAP
create_dib( BOOL v5
)
545 BITMAPINFOHEADER
*hdr
;
547 ret
= GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
| GMEM_ZEROINIT
,
548 sizeof(BITMAPV5HEADER
) + 256 * sizeof(RGBQUAD
) + 16 * 16 * 4 );
549 hdr
= GlobalLock( ret
);
550 hdr
->biSize
= v5
? sizeof(BITMAPV5HEADER
) : sizeof(*hdr
);
554 hdr
->biBitCount
= 32;
555 hdr
->biCompression
= BI_RGB
;
558 BITMAPV5HEADER
*hdr5
= (BITMAPV5HEADER
*)hdr
;
559 hdr5
->bV5RedMask
= 0x0000ff;
560 hdr5
->bV5GreenMask
= 0x00ff00;
561 hdr5
->bV5BlueMask
= 0xff0000;
562 hdr5
->bV5AlphaMask
= 0xff000000;
568 static LRESULT CALLBACK
renderer_winproc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
570 static UINT rendered
;
575 case WM_RENDERFORMAT
:
576 if (wp
< 32) rendered
|= (1 << wp
);
583 return DefWindowProcA( hwnd
, msg
, wp
, lp
);
586 static void test_synthesized(void)
588 static const struct test
594 /* 0 */ { CF_TEXT
, { CF_TEXT
, CF_LOCALE
, CF_OEMTEXT
, CF_UNICODETEXT
}},
595 { CF_OEMTEXT
, { CF_OEMTEXT
, CF_LOCALE
, CF_TEXT
, CF_UNICODETEXT
}},
596 { CF_UNICODETEXT
, { CF_UNICODETEXT
, CF_LOCALE
, CF_TEXT
, CF_OEMTEXT
}},
597 { CF_ENHMETAFILE
, { CF_ENHMETAFILE
, CF_METAFILEPICT
}},
598 { CF_METAFILEPICT
, { CF_METAFILEPICT
, CF_ENHMETAFILE
}},
599 /* 5 */ { CF_BITMAP
, { CF_BITMAP
, CF_DIB
, CF_DIBV5
}},
600 { CF_DIB
, { CF_DIB
, CF_BITMAP
, CF_DIBV5
}},
601 { CF_DIBV5
, { CF_DIBV5
, CF_BITMAP
, CF_DIB
}},
607 UINT cf
, i
, j
, count
, rendered
, seq
, old_seq
;
611 hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
612 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)renderer_winproc
);
614 htext
= create_textA();
617 r
= OpenClipboard(NULL
);
618 ok(r
, "gle %d\n", GetLastError());
619 r
= EmptyClipboard();
620 ok(r
, "gle %d\n", GetLastError());
621 h
= SetClipboardData(CF_TEXT
, htext
);
622 ok(h
== htext
, "got %p\n", h
);
623 h
= SetClipboardData(CF_ENHMETAFILE
, emf
);
624 ok(h
== emf
, "got %p\n", h
);
625 r
= CloseClipboard();
626 ok(r
, "gle %d\n", GetLastError());
628 count
= CountClipboardFormats();
629 ok( count
== 6, "count %u\n", count
);
630 r
= IsClipboardFormatAvailable( CF_TEXT
);
631 ok( r
, "CF_TEXT not available err %d\n", GetLastError());
632 r
= IsClipboardFormatAvailable( CF_LOCALE
);
633 ok( r
, "CF_LOCALE not available err %d\n", GetLastError());
634 r
= IsClipboardFormatAvailable( CF_OEMTEXT
);
635 ok( r
, "CF_OEMTEXT not available err %d\n", GetLastError());
636 r
= IsClipboardFormatAvailable( CF_UNICODETEXT
);
637 ok( r
, "CF_UNICODETEXT not available err %d\n", GetLastError());
638 r
= IsClipboardFormatAvailable( CF_ENHMETAFILE
);
639 ok( r
, "CF_ENHMETAFILE not available err %d\n", GetLastError());
640 r
= IsClipboardFormatAvailable( CF_METAFILEPICT
);
641 ok( r
, "CF_METAFILEPICT not available err %d\n", GetLastError());
643 r
= OpenClipboard(NULL
);
644 ok(r
, "gle %d\n", GetLastError());
645 cf
= EnumClipboardFormats(0);
646 ok(cf
== CF_TEXT
, "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_ENHMETAFILE
, "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_LOCALE
, "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_OEMTEXT
, "cf %08x\n", cf
);
662 data
= GetClipboardData(cf
);
663 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
665 cf
= EnumClipboardFormats(cf
);
666 ok(cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
668 cf
= EnumClipboardFormats(cf
);
669 ok(cf
== CF_METAFILEPICT
, "cf %08x\n", cf
);
670 data
= GetClipboardData(cf
);
671 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
673 cf
= EnumClipboardFormats(cf
);
674 ok(cf
== 0, "cf %08x\n", cf
);
676 r
= EmptyClipboard();
677 ok(r
, "gle %d\n", GetLastError());
679 SetClipboardData( CF_UNICODETEXT
, create_textW() );
680 SetClipboardData( CF_TEXT
, create_textA() );
681 SetClipboardData( CF_OEMTEXT
, create_textA() );
682 r
= CloseClipboard();
683 ok(r
, "gle %d\n", GetLastError());
685 r
= OpenClipboard( NULL
);
686 ok(r
, "gle %d\n", GetLastError());
687 SetLastError( 0xdeadbeef );
688 cf
= EnumClipboardFormats(0);
689 ok( cf
== CF_UNICODETEXT
, "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_TEXT
, "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_OEMTEXT
, "cf %08x\n", cf
);
698 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
699 SetLastError( 0xdeadbeef );
700 cf
= EnumClipboardFormats(cf
);
701 ok( cf
== CF_LOCALE
, "cf %08x\n", cf
);
702 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
703 SetLastError( 0xdeadbeef );
704 cf
= EnumClipboardFormats( cf
);
705 ok( cf
== 0, "cf %08x\n", cf
);
706 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
707 SetLastError( 0xdeadbeef );
708 cf
= EnumClipboardFormats( 0xdead );
709 ok( cf
== 0, "cf %08x\n", cf
);
710 ok( GetLastError() == ERROR_SUCCESS
, "wrong error %u\n", GetLastError() );
712 r
= EmptyClipboard();
713 ok(r
, "gle %d\n", GetLastError());
715 r
= CloseClipboard();
716 ok(r
, "gle %d\n", GetLastError());
718 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
720 r
= OpenClipboard(NULL
);
721 ok(r
, "%u: gle %d\n", i
, GetLastError());
722 r
= EmptyClipboard();
723 ok(r
, "%u: gle %d\n", i
, GetLastError());
725 switch (tests
[i
].format
)
729 SetClipboardData( tests
[i
].format
, create_textA() );
732 SetClipboardData( CF_UNICODETEXT
, create_textW() );
735 SetClipboardData( CF_ENHMETAFILE
, create_emf() );
737 case CF_METAFILEPICT
:
738 SetClipboardData( CF_METAFILEPICT
, create_metafile() );
741 SetClipboardData( CF_BITMAP
, create_bitmap() );
745 SetClipboardData( tests
[i
].format
, create_dib( tests
[i
].format
== CF_DIBV5
));
749 count
= CountClipboardFormats();
750 ok( count
== 1, "%u: count %u\n", i
, count
);
752 r
= CloseClipboard();
753 ok(r
, "%u: gle %d\n", i
, GetLastError());
755 count
= CountClipboardFormats();
756 for (j
= 0; tests
[i
].expected
[j
]; j
++)
758 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
759 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
761 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
763 r
= OpenClipboard( hwnd
);
764 ok(r
, "%u: gle %d\n", i
, GetLastError());
766 for (j
= 0; tests
[i
].expected
[j
]; j
++)
768 cf
= EnumClipboardFormats( cf
);
769 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
770 i
, j
, cf
, tests
[i
].expected
[j
] );
771 if (cf
!= tests
[i
].expected
[j
]) break;
772 old_seq
= GetClipboardSequenceNumber();
773 data
= GetClipboardData( cf
);
775 broken( tests
[i
].format
== CF_DIBV5
&& cf
== CF_DIB
), /* >= Vista */
776 "%u: couldn't get data, cf %04x err %d\n", i
, cf
, GetLastError());
777 seq
= GetClipboardSequenceNumber();
778 ok(seq
== old_seq
, "sequence changed (test %d %d)\n", i
, cf
);
783 UINT
*ptr
= GlobalLock( data
);
784 ok( GlobalSize( data
) == sizeof(*ptr
), "%u: size %lu\n", i
, GlobalSize( data
));
785 ok( *ptr
== GetUserDefaultLCID() ||
786 broken( *ptr
== MAKELANGID( LANG_ENGLISH
, SUBLANG_DEFAULT
)),
787 "%u: CF_LOCALE %08x/%08x\n", i
, *ptr
, GetUserDefaultLCID() );
788 GlobalUnlock( data
);
793 ok( GlobalSize( data
) == 10, "wrong len %ld\n", GlobalSize( data
));
796 ok( GlobalSize( data
) == 10 * sizeof(WCHAR
), "wrong len %ld\n", GlobalSize( data
));
800 if (!tests
[i
].expected
[j
])
802 cf
= EnumClipboardFormats( cf
);
803 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
806 /* now with delayed rendering */
808 r
= EmptyClipboard();
809 ok(r
, "%u: gle %d\n", i
, GetLastError());
811 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
812 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
814 SetClipboardData( tests
[i
].format
, 0 );
815 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
816 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
818 count
= CountClipboardFormats();
819 ok( count
== 1, "%u: count %u\n", i
, count
);
821 r
= CloseClipboard();
822 ok(r
, "%u: gle %d\n", i
, GetLastError());
823 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
824 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
826 count
= CountClipboardFormats();
827 for (j
= 0; tests
[i
].expected
[j
]; j
++)
829 r
= IsClipboardFormatAvailable( tests
[i
].expected
[j
] );
830 ok( r
, "%u: %04x not available\n", i
, tests
[i
].expected
[j
] );
832 ok( count
== j
, "%u: count %u instead of %u\n", i
, count
, j
);
833 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
834 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
836 r
= OpenClipboard(NULL
);
837 ok(r
, "%u: gle %d\n", i
, GetLastError());
839 for (j
= 0; tests
[i
].expected
[j
]; j
++)
841 cf
= EnumClipboardFormats( cf
);
842 ok(cf
== tests
[i
].expected
[j
], "%u.%u: got %04x instead of %04x\n",
843 i
, j
, cf
, tests
[i
].expected
[j
] );
844 if (cf
!= tests
[i
].expected
[j
]) break;
845 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
846 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
847 data
= GetClipboardData( cf
);
848 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
851 ok(data
!= NULL
, "%u: CF_LOCALE no data\n", i
);
852 ok( !rendered
, "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
856 ok(!data
, "%u: format %04x got data %p\n", i
, cf
, data
);
857 ok( rendered
== (1 << tests
[i
].format
),
858 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
859 /* try to render a second time */
860 data
= GetClipboardData( cf
);
861 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
862 ok( rendered
== (1 << tests
[i
].format
),
863 "%u.%u: formats %08x have been rendered\n", i
, j
, rendered
);
866 if (!tests
[i
].expected
[j
])
868 cf
= EnumClipboardFormats( cf
);
869 ok(cf
== 0, "%u: cf %04x\n", i
, cf
);
871 r
= CloseClipboard();
872 ok(r
, "%u: gle %d\n", i
, GetLastError());
873 rendered
= SendMessageA( hwnd
, WM_USER
, 0, 0 );
874 ok( !rendered
, "%u: formats %08x have been rendered\n", i
, rendered
);
877 r
= OpenClipboard(NULL
);
878 ok(r
, "gle %d\n", GetLastError());
879 r
= EmptyClipboard();
880 ok(r
, "gle %d\n", GetLastError());
881 r
= CloseClipboard();
882 ok(r
, "gle %d\n", GetLastError());
883 DestroyWindow( hwnd
);
886 static DWORD WINAPI
clipboard_render_data_thread(void *param
)
888 HANDLE handle
= SetClipboardData( CF_UNICODETEXT
, create_textW() );
889 ok( handle
!= 0, "SetClipboardData failed: %d\n", GetLastError() );
893 static CRITICAL_SECTION clipboard_cs
;
894 static HWND next_wnd
;
895 static UINT wm_drawclipboard
;
896 static UINT wm_clipboardupdate
;
897 static UINT wm_destroyclipboard
;
898 static UINT wm_renderformat
;
899 static UINT nb_formats
;
900 static BOOL cross_thread
;
901 static BOOL do_render_format
;
902 static HANDLE update_event
;
904 static LRESULT CALLBACK
clipboard_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
907 DWORD msg_flags
= InSendMessageEx( NULL
);
910 case WM_DRAWCLIPBOARD
:
911 ok( msg_flags
== (cross_thread
? ISMEX_NOTIFY
: ISMEX_NOSEND
),
912 "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags
);
913 EnterCriticalSection(&clipboard_cs
);
915 LeaveCriticalSection(&clipboard_cs
);
917 case WM_CHANGECBCHAIN
:
918 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
919 "WM_CHANGECBCHAIN wrong flags %x\n", msg_flags
);
920 if (next_wnd
== (HWND
)wp
)
923 SendMessageA(next_wnd
, msg
, wp
, lp
);
925 case WM_DESTROYCLIPBOARD
:
926 ok( msg_flags
== (cross_thread
? ISMEX_SEND
: ISMEX_NOSEND
),
927 "WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags
);
928 wm_destroyclipboard
++;
929 ok( GetClipboardOwner() == hwnd
, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
930 nb_formats
= CountClipboardFormats();
932 case WM_RENDERFORMAT
:
933 ok( !wm_renderformat
, "multiple WM_RENDERFORMAT %04x / %04lx\n", wm_renderformat
, wp
);
934 wm_renderformat
= wp
;
936 if (do_render_format
)
941 old_seq
= GetClipboardSequenceNumber();
942 handle
= SetClipboardData( CF_TEXT
, create_textA() );
943 ok( handle
!= 0, "SetClipboardData failed: %d\n", GetLastError() );
944 seq
= GetClipboardSequenceNumber();
945 ok( seq
== old_seq
, "sequence changed\n" );
948 handle
= CreateThread( NULL
, 0, clipboard_render_data_thread
, NULL
, 0, NULL
);
949 ok( handle
!= NULL
, "CreateThread failed: %d\n", GetLastError() );
950 ok( WaitForSingleObject(handle
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
951 CloseHandle( handle
);
952 seq
= GetClipboardSequenceNumber();
953 ok( seq
== old_seq
, "sequence changed\n" );
957 case WM_CLIPBOARDUPDATE
:
958 ok( msg_flags
== ISMEX_NOSEND
, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags
);
959 EnterCriticalSection(&clipboard_cs
);
960 wm_clipboardupdate
++;
961 SetEvent(update_event
);
962 LeaveCriticalSection(&clipboard_cs
);
965 ChangeClipboardChain(hwnd
, next_wnd
);
969 ret
= wm_drawclipboard
;
970 wm_drawclipboard
= 0;
973 ret
= wm_clipboardupdate
;
974 wm_clipboardupdate
= 0;
977 ret
= wm_destroyclipboard
;
978 wm_destroyclipboard
= 0;
981 ret
= wm_renderformat
;
988 return DefWindowProcA(hwnd
, msg
, wp
, lp
);
991 static void get_clipboard_data_process(void)
996 r
= OpenClipboard(0);
997 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
998 data
= GetClipboardData( CF_UNICODETEXT
);
999 ok( data
!= NULL
, "GetClipboardData failed: %d\n", GetLastError());
1000 r
= CloseClipboard();
1001 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1004 static UINT old_seq
;
1006 static void check_messages_(int line
, HWND win
, UINT seq_diff
, UINT draw
, UINT update
, UINT destroy
, UINT render
)
1009 UINT count
, fmt
, seq
;
1011 seq
= GetClipboardSequenceNumber();
1012 ok_(__FILE__
, line
)(seq
- old_seq
== seq_diff
, "sequence diff %d\n", seq
- old_seq
);
1017 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1020 if (update
&& !broken(!pAddClipboardFormatListener
))
1021 ok(WaitForSingleObject(update_event
, 1000) == WAIT_OBJECT_0
, "wait failed\n");
1023 count
= SendMessageA( win
, WM_USER
+ 1, 0, 0 );
1024 ok_(__FILE__
, line
)(count
== draw
, "WM_DRAWCLIPBOARD %sreceived\n", draw
? "not " : "");
1025 count
= SendMessageA( win
, WM_USER
+ 2, 0, 0 );
1026 ok_(__FILE__
, line
)(count
== update
|| broken(!pAddClipboardFormatListener
),
1027 "WM_CLIPBOARDUPDATE %sreceived\n", update
? "not " : "");
1028 count
= SendMessageA( win
, WM_USER
+ 3, 0, 0 );
1029 ok_(__FILE__
, line
)(count
== destroy
, "WM_DESTROYCLIPBOARD %sreceived\n", destroy
? "not " : "");
1030 fmt
= SendMessageA( win
, WM_USER
+ 4, 0, 0 );
1031 ok_(__FILE__
, line
)(fmt
== render
, "WM_RENDERFORMAT received %04x, expected %04x\n", fmt
, render
);
1033 #define check_messages(a,b,c,d,e,f) check_messages_(__LINE__,a,b,c,d,e,f)
1035 static DWORD WINAPI
clipboard_thread(void *param
)
1037 HWND ret
, win
= param
;
1041 UINT count
, fmt
, formats
;
1043 cross_thread
= (GetWindowThreadProcessId( win
, NULL
) != GetCurrentThreadId());
1044 trace( "%s-threaded test\n", cross_thread
? "multi" : "single" );
1046 old_seq
= GetClipboardSequenceNumber();
1048 EnterCriticalSection(&clipboard_cs
);
1049 SetLastError(0xdeadbeef);
1050 next_wnd
= SetClipboardViewer(win
);
1051 ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
1052 LeaveCriticalSection(&clipboard_cs
);
1054 SetLastError( 0xdeadbeef );
1055 ret
= SetClipboardViewer( (HWND
)0xdead );
1056 ok( !ret
, "SetClipboardViewer succeeded\n" );
1057 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1058 SetLastError( 0xdeadbeef );
1059 r
= ChangeClipboardChain( win
, (HWND
)0xdead );
1060 ok( !r
, "ChangeClipboardChain succeeded\n" );
1061 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1062 SetLastError( 0xdeadbeef );
1063 r
= ChangeClipboardChain( (HWND
)0xdead, next_wnd
);
1064 ok( !r
, "ChangeClipboardChain succeeded\n" );
1065 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1067 if (pAddClipboardFormatListener
)
1069 r
= pAddClipboardFormatListener(win
);
1070 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
1071 SetLastError( 0xdeadbeef );
1072 r
= pAddClipboardFormatListener( win
);
1073 ok( !r
, "AddClipboardFormatListener succeeded\n" );
1074 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1075 SetLastError( 0xdeadbeef );
1076 r
= pAddClipboardFormatListener( (HWND
)0xdead );
1077 ok( !r
, "AddClipboardFormatListener succeeded\n" );
1078 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1079 r
= pAddClipboardFormatListener( GetDesktopWindow() );
1080 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
1081 r
= pRemoveClipboardFormatListener( GetDesktopWindow() );
1082 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1085 check_messages(win
, 0, 1, 0, 0, 0);
1087 SetLastError( 0xdeadbeef );
1088 r
= OpenClipboard( (HWND
)0xdead );
1089 ok( !r
, "OpenClipboard succeeded\n" );
1090 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1092 r
= OpenClipboard(win
);
1093 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1095 check_messages(win
, 0, 0, 0, 0, 0);
1097 r
= EmptyClipboard();
1098 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1100 check_messages(win
, 1, 0, 0, 0, 0);
1102 r
= EmptyClipboard();
1103 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1104 /* sequence changes again, even though it was already empty */
1105 check_messages(win
, 1, 0, 0, 1, 0);
1106 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1107 ok( !count
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1109 handle
= SetClipboardData( CF_TEXT
, create_textA() );
1110 ok(handle
!= 0, "SetClipboardData failed: %d\n", GetLastError());
1112 check_messages(win
, 1, 0, 0, 0, 0);
1114 SetClipboardData( CF_UNICODETEXT
, 0 );
1116 check_messages(win
, 1, 0, 0, 0, 0);
1118 SetClipboardData( CF_UNICODETEXT
, 0 ); /* same data again */
1120 check_messages(win
, 1, 0, 0, 0, 0);
1122 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1123 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1124 ok( !IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1126 EnterCriticalSection(&clipboard_cs
);
1127 r
= CloseClipboard();
1128 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1129 LeaveCriticalSection(&clipboard_cs
);
1131 check_messages(win
, 2, 1, 1, 0, 0);
1133 r
= OpenClipboard(win
);
1134 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1136 check_messages(win
, 0, 0, 0, 0, 0);
1138 ok( IsClipboardFormatAvailable( CF_TEXT
), "CF_TEXT available\n" );
1139 ok( IsClipboardFormatAvailable( CF_UNICODETEXT
), "CF_UNICODETEXT available\n" );
1140 ok( IsClipboardFormatAvailable( CF_OEMTEXT
), "CF_OEMTEXT available\n" );
1142 ok( GetClipboardOwner() == win
, "wrong owner %p\n", GetClipboardOwner());
1143 handle
= GetClipboardData( CF_UNICODETEXT
);
1144 ok( !handle
, "got data for CF_UNICODETEXT\n" );
1145 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1146 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1148 do_render_format
= TRUE
;
1149 handle
= GetClipboardData( CF_OEMTEXT
);
1150 ok( handle
!= NULL
, "didn't get data for CF_OEMTEXT\n" );
1151 fmt
= SendMessageA( win
, WM_USER
+4, 0, 0 );
1152 ok( fmt
== CF_UNICODETEXT
, "WM_RENDERFORMAT received %04x\n", fmt
);
1153 do_render_format
= FALSE
;
1155 SetClipboardData( CF_WAVE
, 0 );
1156 check_messages(win
, 1, 0, 0, 0, 0);
1158 r
= CloseClipboard();
1159 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1160 /* no synthesized format, so CloseClipboard doesn't change the sequence */
1161 check_messages(win
, 0, 1, 1, 0, 0);
1163 r
= OpenClipboard(win
);
1164 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1165 r
= CloseClipboard();
1166 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1167 /* nothing changed */
1168 check_messages(win
, 0, 0, 0, 0, 0);
1170 formats
= CountClipboardFormats();
1171 r
= OpenClipboard(0);
1172 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1173 r
= EmptyClipboard();
1174 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1175 r
= CloseClipboard();
1176 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1178 check_messages(win
, 1, 1, 1, 1, 0);
1179 count
= SendMessageA( win
, WM_USER
+5, 0, 0 );
1180 ok( count
== formats
, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count
);
1182 r
= OpenClipboard(win
);
1183 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1184 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1185 check_messages(win
, 1, 0, 0, 0, 0);
1187 EnterCriticalSection(&clipboard_cs
);
1188 r
= CloseClipboard();
1189 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1190 LeaveCriticalSection(&clipboard_cs
);
1192 check_messages(win
, 0, 1, 1, 0, 0);
1194 run_process( "grab_clipboard 0" );
1198 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1199 cross_thread
= TRUE
;
1200 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1201 cross_thread
= FALSE
;
1203 check_messages(win
, 1, 1, 1, 0, 0);
1205 r
= OpenClipboard(0);
1206 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1207 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1208 check_messages(win
, 1, 0, 0, 0, 0);
1210 EnterCriticalSection(&clipboard_cs
);
1211 r
= CloseClipboard();
1212 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1213 LeaveCriticalSection(&clipboard_cs
);
1215 check_messages(win
, 0, 1, 1, 0, 0);
1217 run_process( "grab_clipboard 1" );
1221 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1222 cross_thread
= TRUE
;
1223 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
1224 cross_thread
= FALSE
;
1226 check_messages(win
, 2, 1, 1, 0, 0);
1228 r
= OpenClipboard(0);
1229 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1230 SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_FIXED
, 1 ));
1231 check_messages(win
, 1, 0, 0, 0, 0);
1233 EnterCriticalSection(&clipboard_cs
);
1234 r
= CloseClipboard();
1235 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1236 LeaveCriticalSection(&clipboard_cs
);
1238 check_messages(win
, 0, 1, 1, 0, 0);
1242 r
= OpenClipboard( win
);
1243 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
1244 r
= EmptyClipboard();
1245 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
1246 SetClipboardData( CF_TEXT
, 0 );
1247 r
= CloseClipboard();
1248 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
1250 do_render_format
= TRUE
;
1251 old_seq
= GetClipboardSequenceNumber();
1252 run_process( "get_clipboard_data" );
1253 do_render_format
= FALSE
;
1255 check_messages(win
, 0, 1, 1, 0, CF_TEXT
);
1258 r
= PostMessageA(win
, WM_USER
, 0, 0);
1259 ok(r
, "PostMessage failed: %d\n", GetLastError());
1261 if (pRemoveClipboardFormatListener
)
1263 r
= pRemoveClipboardFormatListener(win
);
1264 ok( r
, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1265 SetLastError( 0xdeadbeef );
1266 r
= pRemoveClipboardFormatListener(win
);
1267 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1268 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1269 SetLastError( 0xdeadbeef );
1270 r
= pRemoveClipboardFormatListener( (HWND
)0xdead );
1271 ok( !r
, "RemoveClipboardFormatListener succeeded\n" );
1272 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error %u\n", GetLastError() );
1277 static void test_messages(void)
1285 InitializeCriticalSection(&clipboard_cs
);
1286 update_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1288 memset(&cls
, 0, sizeof(cls
));
1289 cls
.lpfnWndProc
= clipboard_wnd_proc
;
1290 cls
.hInstance
= GetModuleHandleA(NULL
);
1291 cls
.lpszClassName
= "clipboard_test";
1292 RegisterClassA(&cls
);
1294 win
= CreateWindowA("clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0);
1295 ok(win
!= NULL
, "CreateWindow failed: %d\n", GetLastError());
1297 thread
= CreateThread(NULL
, 0, clipboard_thread
, (void*)win
, 0, &tid
);
1298 ok(thread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1300 while(GetMessageA(&msg
, NULL
, 0, 0))
1302 ok( msg
.message
!= WM_DRAWCLIPBOARD
, "WM_DRAWCLIPBOARD was posted\n" );
1303 TranslateMessage(&msg
);
1304 DispatchMessageA(&msg
);
1307 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
1308 CloseHandle(thread
);
1310 DestroyWindow( win
);
1312 /* same tests again but inside a single thread */
1314 win
= CreateWindowA( "clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0 );
1315 ok( win
!= NULL
, "CreateWindow failed: %d\n", GetLastError() );
1317 clipboard_thread( win
);
1318 DestroyWindow( win
);
1320 UnregisterClassA("clipboard_test", GetModuleHandleA(NULL
));
1321 DeleteCriticalSection(&clipboard_cs
);
1324 static BOOL
is_moveable( HANDLE handle
)
1326 void *ptr
= GlobalLock( handle
);
1327 if (ptr
) GlobalUnlock( handle
);
1328 return ptr
&& ptr
!= handle
;
1331 static BOOL
is_fixed( HANDLE handle
)
1333 void *ptr
= GlobalLock( handle
);
1334 if (ptr
) GlobalUnlock( handle
);
1335 return ptr
&& ptr
== handle
;
1338 static BOOL
is_freed( HANDLE handle
)
1340 return !GlobalSize( handle
);
1343 static UINT format_id
;
1344 static HBITMAP bitmap
, bitmap2
;
1345 static HPALETTE palette
;
1346 static const LOGPALETTE logpalette
= { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}};
1348 static void test_handles( HWND hwnd
)
1350 HGLOBAL h
, htext
, htext2
, htext3
, htext4
, htext5
;
1351 HGLOBAL hfixed
, hfixed2
, hmoveable
, empty_fixed
, empty_moveable
;
1353 UINT format_id2
= RegisterClipboardFormatA( "another format" );
1356 HBITMAP bitmap_temp
;
1358 BOOL is_owner
= (GetWindowThreadProcessId( hwnd
, &process
) && process
== GetCurrentProcessId());
1360 trace( "hwnd %p\n", hwnd
);
1361 htext
= create_textA();
1362 htext2
= create_textA();
1363 htext3
= create_textA();
1364 htext4
= create_textA();
1365 htext5
= create_textA();
1366 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
1367 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
1368 palette
= CreatePalette( &logpalette
);
1370 hfixed
= GlobalAlloc( GMEM_FIXED
, 17 );
1371 hfixed2
= GlobalAlloc( GMEM_FIXED
, 17 );
1372 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1373 ok( GlobalSize( hfixed
) == 17, "wrong size %lu\n", GlobalSize( hfixed
));
1375 hmoveable
= GlobalAlloc( GMEM_MOVEABLE
, 23 );
1376 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1377 ok( GlobalSize( hmoveable
) == 23, "wrong size %lu\n", GlobalSize( hmoveable
));
1379 empty_fixed
= GlobalAlloc( GMEM_FIXED
, 0 );
1380 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1382 empty_moveable
= GlobalAlloc( GMEM_MOVEABLE
, 0 );
1383 /* discarded handles can't be GlobalLock'ed */
1384 ok( is_freed( empty_moveable
), "expected free mem %p\n", empty_moveable
);
1386 r
= OpenClipboard( hwnd
);
1387 ok( r
, "gle %d\n", GetLastError() );
1388 r
= EmptyClipboard();
1389 ok( r
, "gle %d\n", GetLastError() );
1391 h
= SetClipboardData( CF_TEXT
, htext
);
1392 ok( h
== htext
, "got %p\n", h
);
1393 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1394 h
= SetClipboardData( format_id
, htext2
);
1395 ok( h
== htext2
, "got %p\n", h
);
1396 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1397 bitmap_temp
= CreateBitmap( 10, 10, 1, 1, NULL
);
1398 h
= SetClipboardData( CF_BITMAP
, bitmap_temp
);
1399 ok( h
== bitmap_temp
, "got %p\n", h
);
1400 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1401 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1402 ok( h
== bitmap
, "got %p\n", h
);
1403 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1404 ok( !GetObjectType( bitmap_temp
), "expected free object %p\n", bitmap_temp
);
1405 h
= SetClipboardData( CF_DSPBITMAP
, bitmap2
);
1406 ok( h
== bitmap2
, "got %p\n", h
);
1407 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1408 h
= SetClipboardData( CF_PALETTE
, palette
);
1409 ok( h
== palette
, "got %p\n", h
);
1410 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1411 h
= SetClipboardData( CF_GDIOBJFIRST
+ 3, htext3
);
1412 ok( h
== htext3
, "got %p\n", h
);
1413 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1414 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, htext5
);
1415 ok( h
== htext5
, "got %p\n", h
);
1416 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1417 h
= SetClipboardData( format_id2
, empty_moveable
);
1418 ok( !h
, "got %p\n", h
);
1419 GlobalFree( empty_moveable
);
1421 if (0) /* crashes on vista64 */
1423 ptr
= HeapAlloc( GetProcessHeap(), 0, 0 );
1424 h
= SetClipboardData( format_id2
, ptr
);
1425 ok( !h
, "got %p\n", h
);
1426 HeapFree( GetProcessHeap(), 0, ptr
);
1429 h
= SetClipboardData( format_id2
, empty_fixed
);
1430 ok( h
== empty_fixed
, "got %p\n", h
);
1431 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1432 h
= SetClipboardData( 0xdeadbeef, hfixed2
);
1433 ok( h
== hfixed2
, "got %p\n", h
);
1434 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1435 h
= SetClipboardData( 0xdeadbabe, hmoveable
);
1436 ok( h
== hmoveable
, "got %p\n", h
);
1437 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1439 ptr
= HeapAlloc( GetProcessHeap(), 0, 37 );
1440 h
= SetClipboardData( 0xdeadfade, ptr
);
1441 ok( h
== ptr
|| !h
, "got %p\n", h
);
1442 if (!h
) /* heap blocks are rejected on >= win8 */
1444 HeapFree( GetProcessHeap(), 0, ptr
);
1448 data
= GetClipboardData( CF_TEXT
);
1449 ok( data
== htext
, "wrong data %p\n", data
);
1450 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1452 data
= GetClipboardData( format_id
);
1453 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1454 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1456 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1457 ok( data
== htext3
, "wrong data %p\n", data
);
1458 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1460 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1461 ok( data
== htext5
, "wrong data %p\n", data
);
1462 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1464 data
= GetClipboardData( format_id2
);
1465 ok( data
== empty_fixed
, "wrong data %p\n", data
);
1466 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1468 data
= GetClipboardData( 0xdeadbeef );
1469 ok( data
== hfixed2
, "wrong data %p\n", data
);
1470 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1472 data
= GetClipboardData( 0xdeadbabe );
1473 ok( data
== hmoveable
, "wrong data %p\n", data
);
1474 ok( is_moveable( data
), "expected moveable mem %p\n", data
);
1476 data
= GetClipboardData( 0xdeadfade );
1477 ok( data
== ptr
, "wrong data %p\n", data
);
1479 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, htext4
);
1480 ok( h
== htext4
, "got %p\n", h
);
1481 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1482 ok( is_freed( htext5
), "expected freed mem %p\n", htext5
);
1484 h
= SetClipboardData( 0xdeadbeef, hfixed
);
1485 ok( h
== hfixed
, "got %p\n", h
);
1486 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1487 if (0) /* this test is unreliable / crashes */
1488 ok( is_freed( hfixed2
), "expected freed mem %p\n", hfixed2
);
1490 r
= CloseClipboard();
1491 ok( r
, "gle %d\n", GetLastError() );
1493 /* data handles are still valid */
1494 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1495 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext2
);
1496 ok( is_moveable( htext3
), "expected moveable mem %p\n", htext3
);
1497 ok( is_moveable( htext4
), "expected moveable mem %p\n", htext4
);
1498 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1499 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1500 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1501 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1502 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1503 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1505 r
= OpenClipboard( hwnd
);
1506 ok( r
, "gle %d\n", GetLastError() );
1508 /* and now they are freed, unless we are the owner */
1511 ok( is_freed( htext
), "expected freed mem %p\n", htext
);
1512 ok( is_freed( htext2
), "expected freed mem %p\n", htext2
);
1513 ok( is_freed( htext3
), "expected freed mem %p\n", htext3
);
1514 ok( is_freed( htext4
), "expected freed mem %p\n", htext4
);
1515 ok( is_freed( hmoveable
), "expected freed mem %p\n", hmoveable
);
1517 data
= GetClipboardData( CF_TEXT
);
1518 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1520 data
= GetClipboardData( format_id
);
1521 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1523 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1524 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1526 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1527 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1529 data
= GetClipboardData( format_id2
);
1530 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1531 ok( GlobalSize( data
) == 1, "wrong size %lu\n", GlobalSize( data
));
1533 data
= GetClipboardData( 0xdeadbeef );
1534 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1535 ok( GlobalSize( data
) == 17, "wrong size %lu\n", GlobalSize( data
));
1537 data
= GetClipboardData( 0xdeadbabe );
1538 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1539 ok( GlobalSize( data
) == 23, "wrong size %lu\n", GlobalSize( data
));
1541 data
= GetClipboardData( 0xdeadfade );
1542 ok( is_fixed( data
) || !ptr
, "expected fixed mem %p\n", data
);
1543 if (ptr
) ok( GlobalSize( data
) == 37, "wrong size %lu\n", GlobalSize( data
));
1547 ok( is_moveable( htext
), "expected moveable mem %p\n", htext
);
1548 ok( is_moveable( htext2
), "expected moveable mem %p\n", htext2
);
1549 ok( is_moveable( htext3
), "expected moveable mem %p\n", htext3
);
1550 ok( is_moveable( htext4
), "expected moveable mem %p\n", htext4
);
1551 ok( is_moveable( hmoveable
), "expected moveable mem %p\n", hmoveable
);
1553 data
= GetClipboardData( CF_TEXT
);
1554 ok( data
== htext
, "wrong data %p\n", data
);
1556 data
= GetClipboardData( format_id
);
1557 ok( data
== htext2
, "wrong data %p, cf %08x\n", data
, format_id
);
1559 data
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1560 ok( data
== htext3
, "wrong data %p\n", data
);
1562 data
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1563 ok( data
== htext4
, "wrong data %p\n", data
);
1565 data
= GetClipboardData( format_id2
);
1566 ok( data
== empty_fixed
, "wrong data %p\n", data
);
1568 data
= GetClipboardData( 0xdeadbeef );
1569 ok( data
== hfixed
, "wrong data %p\n", data
);
1571 data
= GetClipboardData( 0xdeadbabe );
1572 ok( data
== hmoveable
, "wrong data %p\n", data
);
1574 data
= GetClipboardData( 0xdeadfade );
1575 ok( data
== ptr
, "wrong data %p\n", data
);
1578 data
= GetClipboardData( CF_OEMTEXT
);
1579 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1580 data
= GetClipboardData( CF_UNICODETEXT
);
1581 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1582 data
= GetClipboardData( CF_LOCALE
);
1583 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1584 data
= GetClipboardData( CF_BITMAP
);
1585 ok( data
== bitmap
, "expected bitmap %p\n", data
);
1586 data
= GetClipboardData( CF_DSPBITMAP
);
1587 ok( data
== bitmap2
, "expected bitmap %p\n", data
);
1588 data
= GetClipboardData( CF_PALETTE
);
1589 ok( data
== palette
, "expected palette %p\n", data
);
1590 data
= GetClipboardData( CF_DIB
);
1591 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1592 data
= GetClipboardData( CF_DIBV5
);
1593 ok( is_fixed( data
), "expected fixed mem %p\n", data
);
1595 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1596 ok( GetObjectType( bitmap2
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap2
);
1597 ok( GetObjectType( palette
) == OBJ_PAL
, "expected palette %p\n", palette
);
1598 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1599 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1601 r
= EmptyClipboard();
1602 ok( r
, "gle %d\n", GetLastError() );
1604 /* w2003, w2008 don't seem to free the data here */
1605 ok( is_freed( htext
) || broken( !is_freed( htext
)), "expected freed mem %p\n", htext
);
1606 ok( is_freed( htext2
) || broken( !is_freed( htext2
)), "expected freed mem %p\n", htext2
);
1607 ok( is_freed( htext3
) || broken( !is_freed( htext3
)), "expected freed mem %p\n", htext3
);
1608 ok( is_freed( htext4
) || broken( !is_freed( htext4
)), "expected freed mem %p\n", htext4
);
1609 ok( is_freed( hmoveable
) || broken( !is_freed( hmoveable
)), "expected freed mem %p\n", hmoveable
);
1610 ok( is_fixed( empty_fixed
), "expected fixed mem %p\n", empty_fixed
);
1611 ok( is_fixed( hfixed
), "expected fixed mem %p\n", hfixed
);
1612 ok( !GetObjectType( bitmap
), "expected freed handle %p\n", bitmap
);
1613 ok( !GetObjectType( bitmap2
), "expected freed handle %p\n", bitmap2
);
1614 ok( !GetObjectType( palette
), "expected freed handle %p\n", palette
);
1616 r
= CloseClipboard();
1617 ok( r
, "gle %d\n", GetLastError() );
1620 static DWORD WINAPI
test_handles_thread( void *arg
)
1622 trace( "running from different thread\n" );
1623 test_handles( (HWND
)arg
);
1627 static DWORD WINAPI
test_handles_thread2( void *arg
)
1633 r
= OpenClipboard( 0 );
1634 ok( r
, "gle %d\n", GetLastError() );
1635 h
= GetClipboardData( CF_TEXT
);
1636 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1637 ptr
= GlobalLock( h
);
1638 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1640 h
= GetClipboardData( format_id
);
1641 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1642 ptr
= GlobalLock( h
);
1643 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1645 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1646 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1647 ptr
= GlobalLock( h
);
1648 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1650 trace( "gdiobj %p\n", h
);
1651 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1652 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1653 ptr
= GlobalLock( h
);
1654 if (ptr
) ok( !strcmp( "test", ptr
), "wrong data '%.5s'\n", ptr
);
1656 trace( "private %p\n", h
);
1657 h
= GetClipboardData( CF_BITMAP
);
1658 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1659 ok( h
== bitmap
, "different bitmap %p / %p\n", h
, bitmap
);
1660 trace( "bitmap %p\n", h
);
1661 h
= GetClipboardData( CF_DSPBITMAP
);
1662 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1663 ok( h
== bitmap2
, "different bitmap %p / %p\n", h
, bitmap2
);
1664 trace( "bitmap2 %p\n", h
);
1665 h
= GetClipboardData( CF_PALETTE
);
1666 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1667 ok( h
== palette
, "different palette %p / %p\n", h
, palette
);
1668 trace( "palette %p\n", h
);
1669 h
= GetClipboardData( CF_DIB
);
1670 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1671 h
= GetClipboardData( CF_DIBV5
);
1672 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1673 r
= CloseClipboard();
1674 ok( r
, "gle %d\n", GetLastError() );
1678 static void test_handles_process( const char *str
)
1687 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
1688 r
= OpenClipboard( 0 );
1689 ok( r
, "gle %d\n", GetLastError() );
1690 h
= GetClipboardData( CF_TEXT
);
1691 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1692 ptr
= GlobalLock( h
);
1693 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1695 h
= GetClipboardData( format_id
);
1696 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1697 ptr
= GlobalLock( h
);
1698 if (ptr
) ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1700 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1701 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1702 ptr
= GlobalLock( h
);
1703 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1705 trace( "gdiobj %p\n", h
);
1706 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1707 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1708 ptr
= GlobalLock( h
);
1709 ok( !strcmp( str
, ptr
), "wrong data '%.5s'\n", ptr
);
1711 trace( "private %p\n", h
);
1712 h
= GetClipboardData( CF_BITMAP
);
1713 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1714 ok( GetObjectW( h
, sizeof(bm
), &bm
) == sizeof(bm
), "GetObject %p failed\n", h
);
1715 ok( bm
.bmWidth
== 13 && bm
.bmHeight
== 17, "wrong bitmap %ux%u\n", bm
.bmWidth
, bm
.bmHeight
);
1716 trace( "bitmap %p\n", h
);
1717 h
= GetClipboardData( CF_DSPBITMAP
);
1718 ok( !GetObjectType( h
), "expected invalid object %p\n", h
);
1719 trace( "bitmap2 %p\n", h
);
1720 h
= GetClipboardData( CF_PALETTE
);
1721 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1722 ok( GetPaletteEntries( h
, 0, 1, &entry
) == 1, "GetPaletteEntries %p failed\n", h
);
1723 ok( entry
.peRed
== 0x12 && entry
.peGreen
== 0x34 && entry
.peBlue
== 0x56,
1724 "wrong color %02x,%02x,%02x\n", entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
1725 trace( "palette %p\n", h
);
1726 h
= GetClipboardData( CF_METAFILEPICT
);
1727 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1731 ok( GetObjectType( ((METAFILEPICT
*)h
)->hMF
) == OBJ_METAFILE
,
1732 "wrong object %p\n", ((METAFILEPICT
*)h
)->hMF
);
1733 trace( "metafile %p\n", h
);
1734 h
= GetClipboardData( CF_DSPMETAFILEPICT
);
1735 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1739 ok( GetObjectType( ((METAFILEPICT
*)h
)->hMF
) == OBJ_METAFILE
,
1740 "wrong object %p\n", ((METAFILEPICT
*)h
)->hMF
);
1741 trace( "metafile2 %p\n", h
);
1742 h
= GetClipboardData( CF_ENHMETAFILE
);
1743 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
1744 ok( GetEnhMetaFileBits( h
, sizeof(buffer
), buffer
) > sizeof(ENHMETAHEADER
),
1745 "GetEnhMetaFileBits failed on %p\n", h
);
1746 ok( ((ENHMETAHEADER
*)buffer
)->nRecords
== 3,
1747 "wrong records %u\n", ((ENHMETAHEADER
*)buffer
)->nRecords
);
1748 trace( "enhmetafile %p\n", h
);
1749 h
= GetClipboardData( CF_DSPENHMETAFILE
);
1750 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
1751 ok( GetEnhMetaFileBits( h
, sizeof(buffer
), buffer
) > sizeof(ENHMETAHEADER
),
1752 "GetEnhMetaFileBits failed on %p\n", h
);
1753 ok( ((ENHMETAHEADER
*)buffer
)->nRecords
== 3,
1754 "wrong records %u\n", ((ENHMETAHEADER
*)buffer
)->nRecords
);
1755 trace( "enhmetafile2 %p\n", h
);
1756 h
= GetClipboardData( CF_DIB
);
1757 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1758 h
= GetClipboardData( CF_DIBV5
);
1759 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1760 r
= CloseClipboard();
1761 ok( r
, "gle %d\n", GetLastError() );
1764 static void test_handles_process_open( const char *str
)
1766 HANDLE h
, text
= GlobalAlloc( GMEM_DDESHARE
|GMEM_MOVEABLE
, strlen(str
) + 1 );
1767 char *ptr
= GlobalLock( text
);
1770 GlobalUnlock( text
);
1772 /* clipboard already open by parent process */
1773 h
= SetClipboardData( CF_TEXT
, text
);
1774 ok( h
== text
, "wrong mem %p / %p\n", h
, text
);
1775 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1778 static void test_handles_process_dib( const char *str
)
1783 r
= OpenClipboard( 0 );
1784 ok( r
, "gle %d\n", GetLastError() );
1785 h
= GetClipboardData( CF_BITMAP
);
1786 ok( !GetObjectType( h
), "expected invalid object %p\n", h
);
1787 trace( "dibsection %p\n", h
);
1788 r
= CloseClipboard();
1789 ok( r
, "gle %d\n", GetLastError() );
1792 static void test_data_handles(void)
1797 HWND hwnd
= CreateWindowA( "static", NULL
, WS_POPUP
, 0, 0, 10, 10, 0, 0, 0, NULL
);
1801 ok( hwnd
!= 0, "window creation failed\n" );
1802 format_id
= RegisterClipboardFormatA( "my_cool_clipboard_format" );
1804 test_handles( GetDesktopWindow() );
1805 test_handles( hwnd
);
1806 run_thread( test_handles_thread
, hwnd
, __LINE__
);
1808 bitmap
= CreateBitmap( 13, 17, 1, 1, NULL
);
1809 bitmap2
= CreateBitmap( 10, 10, 1, 1, NULL
);
1810 palette
= CreatePalette( &logpalette
);
1812 r
= OpenClipboard( hwnd
);
1813 ok( r
, "gle %d\n", GetLastError() );
1814 r
= EmptyClipboard();
1815 ok( r
, "gle %d\n", GetLastError() );
1816 h
= SetClipboardData( CF_TEXT
, create_textA() );
1817 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1818 h
= SetClipboardData( format_id
, create_textA() );
1819 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1820 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1821 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1822 h
= SetClipboardData( CF_DSPBITMAP
, bitmap2
);
1823 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1824 h
= SetClipboardData( CF_PALETTE
, palette
);
1825 ok( GetObjectType( h
) == OBJ_PAL
, "expected palette %p\n", h
);
1826 h
= SetClipboardData( CF_METAFILEPICT
, create_metafile() );
1827 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1828 trace( "metafile %p\n", h
);
1829 h
= SetClipboardData( CF_DSPMETAFILEPICT
, create_metafile() );
1830 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1831 trace( "metafile2 %p\n", h
);
1832 h
= SetClipboardData( CF_ENHMETAFILE
, create_emf() );
1833 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
1834 trace( "enhmetafile %p\n", h
);
1835 h
= SetClipboardData( CF_DSPENHMETAFILE
, create_emf() );
1836 ok( GetObjectType( h
) == OBJ_ENHMETAFILE
, "expected enhmetafile %p\n", h
);
1837 trace( "enhmetafile2 %p\n", h
);
1838 h
= SetClipboardData( CF_GDIOBJFIRST
+ 3, create_textA() );
1839 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1840 h
= SetClipboardData( CF_PRIVATEFIRST
+ 7, create_textA() );
1841 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1842 r
= CloseClipboard();
1843 ok( r
, "gle %d\n", GetLastError() );
1845 run_thread( test_handles_thread2
, 0, __LINE__
);
1846 run_process( "handles test" );
1848 r
= OpenClipboard( hwnd
);
1849 ok( r
, "gle %d\n", GetLastError() );
1850 h
= GetClipboardData( CF_TEXT
);
1851 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1852 h
= GetClipboardData( format_id
);
1853 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1854 h
= GetClipboardData( CF_GDIOBJFIRST
+ 3 );
1855 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1856 h
= GetClipboardData( CF_PRIVATEFIRST
+ 7 );
1857 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1859 r
= EmptyClipboard();
1860 ok( r
, "gle %d\n", GetLastError() );
1861 text
= create_textA();
1862 h
= SetClipboardData( CF_TEXT
, text
);
1863 ok( is_moveable( h
), "expected moveable mem %p\n", h
);
1865 run_process( "handles_open foobar" );
1867 ok( is_moveable( text
), "expected moveable mem %p\n", text
);
1868 h
= GetClipboardData( CF_TEXT
);
1869 ok( is_fixed( h
), "expected fixed mem %p\n", h
);
1870 ok( is_moveable( text
), "expected moveable mem %p\n", text
);
1871 ptr
= GlobalLock( h
);
1872 ok( !strcmp( ptr
, "foobar" ), "wrong data '%.8s'\n", ptr
);
1875 r
= EmptyClipboard();
1876 ok( r
, "gle %d\n", GetLastError() );
1877 ok( is_fixed( h
), "expected free mem %p\n", h
);
1878 ok( is_freed( text
) || broken( is_moveable(text
) ), /* w2003, w2008 */
1879 "expected free mem %p\n", text
);
1880 r
= CloseClipboard();
1881 ok( r
, "gle %d\n", GetLastError() );
1883 /* test CF_BITMAP with a DIB section */
1884 memset( &bmi
, 0, sizeof(bmi
) );
1885 bmi
.bmiHeader
.biSize
= sizeof( bmi
.bmiHeader
);
1886 bmi
.bmiHeader
.biWidth
= 29;
1887 bmi
.bmiHeader
.biHeight
= 13;
1888 bmi
.bmiHeader
.biPlanes
= 1;
1889 bmi
.bmiHeader
.biBitCount
= 32;
1890 bitmap
= CreateDIBSection( 0, &bmi
, DIB_RGB_COLORS
, &bits
, 0, 0 );
1892 r
= OpenClipboard( hwnd
);
1893 ok( r
, "gle %d\n", GetLastError() );
1894 r
= EmptyClipboard();
1895 ok( r
, "gle %d\n", GetLastError() );
1896 h
= SetClipboardData( CF_BITMAP
, bitmap
);
1897 ok( GetObjectType( h
) == OBJ_BITMAP
, "expected bitmap %p\n", h
);
1898 trace( "dibsection %p\n", h
);
1899 r
= CloseClipboard();
1900 ok( r
, "gle %d\n", GetLastError() );
1902 run_process( "handles_dib dummy" );
1904 r
= OpenClipboard( hwnd
);
1905 ok( r
, "gle %d\n", GetLastError() );
1906 ok( GetObjectType( bitmap
) == OBJ_BITMAP
, "expected bitmap %p\n", bitmap
);
1907 r
= EmptyClipboard();
1908 ok( r
, "gle %d\n", GetLastError() );
1909 ok( !GetObjectType( bitmap
), "expected deleted %p\n", bitmap
);
1910 r
= CloseClipboard();
1911 ok( r
, "gle %d\n", GetLastError() );
1913 DestroyWindow( hwnd
);
1916 static void test_GetUpdatedClipboardFormats(void)
1919 UINT count
, formats
[256];
1921 if (!pGetUpdatedClipboardFormats
)
1923 win_skip( "GetUpdatedClipboardFormats not supported\n" );
1928 r
= pGetUpdatedClipboardFormats( NULL
, 0, &count
);
1929 ok( r
, "gle %d\n", GetLastError() );
1930 ok( !count
, "wrong count %u\n", count
);
1933 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
1934 ok( r
, "gle %d\n", GetLastError() );
1935 ok( !count
, "wrong count %u\n", count
);
1937 SetLastError( 0xdeadbeef );
1938 r
= pGetUpdatedClipboardFormats( formats
, 256, NULL
);
1939 ok( !r
, "succeeded\n" );
1940 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1943 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1944 ok( r
, "gle %d\n", GetLastError() );
1945 ok( !count
, "wrong count %u\n", count
);
1947 r
= OpenClipboard( 0 );
1948 ok( r
, "gle %d\n", GetLastError() );
1949 r
= EmptyClipboard();
1950 ok( r
, "gle %d\n", GetLastError() );
1953 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1954 ok( r
, "gle %d\n", GetLastError() );
1955 ok( !count
, "wrong count %u\n", count
);
1957 SetClipboardData( CF_UNICODETEXT
, 0 );
1960 memset( formats
, 0xcc, sizeof(formats
) );
1961 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1962 ok( r
, "gle %d\n", GetLastError() );
1963 ok( count
== 1, "wrong count %u\n", count
);
1964 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
1965 ok( formats
[1] == 0xcccccccc, "wrong format %u\n", formats
[1] );
1967 SetClipboardData( CF_TEXT
, 0 );
1969 memset( formats
, 0xcc, sizeof(formats
) );
1970 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1971 ok( r
, "gle %d\n", GetLastError() );
1972 ok( count
== 2, "wrong count %u\n", count
);
1973 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
1974 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
1975 ok( formats
[2] == 0xcccccccc, "wrong format %u\n", formats
[2] );
1977 SetLastError( 0xdeadbeef );
1979 r
= pGetUpdatedClipboardFormats( formats
, 0, &count
);
1980 ok( !r
, "succeeded\n" );
1981 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
1982 ok( count
== 2, "wrong count %u\n", count
);
1984 SetLastError( 0xdeadbeef );
1986 r
= pGetUpdatedClipboardFormats( formats
, 1, &count
);
1987 ok( !r
, "succeeded\n" );
1988 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
1989 ok( count
== 2, "wrong count %u\n", count
);
1991 r
= CloseClipboard();
1992 ok( r
, "gle %d\n", GetLastError() );
1995 memset( formats
, 0xcc, sizeof(formats
) );
1996 r
= pGetUpdatedClipboardFormats( formats
, 256, &count
);
1997 ok( r
, "gle %d\n", GetLastError() );
1998 ok( count
== 4, "wrong count %u\n", count
);
1999 ok( formats
[0] == CF_UNICODETEXT
, "wrong format %u\n", formats
[0] );
2000 ok( formats
[1] == CF_TEXT
, "wrong format %u\n", formats
[1] );
2001 ok( formats
[2] == CF_LOCALE
, "wrong format %u\n", formats
[2] );
2002 ok( formats
[3] == CF_OEMTEXT
, "wrong format %u\n", formats
[3] );
2003 ok( formats
[4] == 0xcccccccc, "wrong format %u\n", formats
[4] );
2006 memset( formats
, 0xcc, sizeof(formats
) );
2007 r
= pGetUpdatedClipboardFormats( formats
, 2, &count
);
2008 ok( !r
, "gle %d\n", GetLastError() );
2009 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %u\n", GetLastError() );
2010 ok( count
== 4, "wrong count %u\n", count
);
2011 ok( formats
[0] == 0xcccccccc, "wrong format %u\n", formats
[0] );
2014 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2015 ok( !r
, "gle %d\n", GetLastError() );
2016 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2017 ok( count
== 4, "wrong count %u\n", count
);
2020 r
= pGetUpdatedClipboardFormats( NULL
, 256, &count
);
2021 ok( !r
, "gle %d\n", GetLastError() );
2022 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2023 ok( count
== 4, "wrong count %u\n", count
);
2033 { "foo", {0}, 3 }, /* 0 */
2035 { "foo\0bar", {0}, 7 },
2036 { "foo\0bar", {0}, 8 },
2037 { "", {'f','o','o'}, 3 * sizeof(WCHAR
) },
2038 { "", {'f','o','o',0}, 4 * sizeof(WCHAR
) }, /* 5 */
2039 { "", {'f','o','o',0,'b','a','r'}, 7 * sizeof(WCHAR
) },
2040 { "", {'f','o','o',0,'b','a','r',0}, 8 * sizeof(WCHAR
) },
2041 { "", {'f','o','o'}, 1 },
2042 { "", {'f','o','o'}, 2 },
2043 { "", {'f','o','o'}, 5 }, /* 10 */
2044 { "", {'f','o','o',0}, 7 },
2045 { "", {'f','o','o',0}, 9 },
2048 static void test_string_data(void)
2057 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
2059 /* 1-byte Unicode strings crash on Win64 */
2061 if (!test_data
[i
].strA
[0] && test_data
[i
].len
< sizeof(WCHAR
)) continue;
2063 r
= OpenClipboard( 0 );
2064 ok( r
, "gle %d\n", GetLastError() );
2065 r
= EmptyClipboard();
2066 ok( r
, "gle %d\n", GetLastError() );
2067 data
= GlobalAlloc( GMEM_FIXED
, test_data
[i
].len
);
2068 if (test_data
[i
].strA
[0])
2070 memcpy( data
, test_data
[i
].strA
, test_data
[i
].len
);
2071 SetClipboardData( CF_TEXT
, data
);
2072 memcpy( bufferA
, test_data
[i
].strA
, test_data
[i
].len
);
2073 bufferA
[test_data
[i
].len
- 1] = 0;
2074 ok( !memcmp( data
, bufferA
, test_data
[i
].len
),
2075 "%u: wrong data %.*s\n", i
, test_data
[i
].len
, (char *)data
);
2079 memcpy( data
, test_data
[i
].strW
, test_data
[i
].len
);
2080 SetClipboardData( CF_UNICODETEXT
, data
);
2081 memcpy( bufferW
, test_data
[i
].strW
, test_data
[i
].len
);
2082 bufferW
[(test_data
[i
].len
+ 1) / sizeof(WCHAR
) - 1] = 0;
2083 ok( !memcmp( data
, bufferW
, test_data
[i
].len
),
2084 "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, (test_data
[i
].len
+ 1) / sizeof(WCHAR
) ));
2086 r
= CloseClipboard();
2087 ok( r
, "gle %d\n", GetLastError() );
2088 sprintf( cmd
, "string_data %u", i
);
2093 static void test_string_data_process( int i
)
2101 r
= OpenClipboard( 0 );
2102 ok( r
, "gle %d\n", GetLastError() );
2103 if (test_data
[i
].strA
[0])
2105 data
= GetClipboardData( CF_TEXT
);
2106 ok( data
!= 0, "%u: could not get data\n", i
);
2107 len
= GlobalSize( data
);
2108 ok( len
== test_data
[i
].len
, "%u: wrong size %u / %u\n", i
, len
, test_data
[i
].len
);
2109 memcpy( bufferA
, test_data
[i
].strA
, test_data
[i
].len
);
2110 bufferA
[test_data
[i
].len
- 1] = 0;
2111 ok( !memcmp( data
, bufferA
, len
), "%u: wrong data %.*s\n", i
, len
, (char *)data
);
2112 data
= GetClipboardData( CF_UNICODETEXT
);
2113 ok( data
!= 0, "%u: could not get data\n", i
);
2114 len
= GlobalSize( data
);
2115 len2
= MultiByteToWideChar( CP_ACP
, 0, bufferA
, test_data
[i
].len
, bufferW
, 12 );
2116 ok( len
== len2
* sizeof(WCHAR
), "%u: wrong size %u / %u\n", i
, len
, len2
);
2117 ok( !memcmp( data
, bufferW
, len
), "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, len2
));
2121 data
= GetClipboardData( CF_UNICODETEXT
);
2122 ok( data
!= 0, "%u: could not get data\n", i
);
2123 len
= GlobalSize( data
);
2124 ok( len
== test_data
[i
].len
, "%u: wrong size %u / %u\n", i
, len
, test_data
[i
].len
);
2125 memcpy( bufferW
, test_data
[i
].strW
, test_data
[i
].len
);
2126 bufferW
[(test_data
[i
].len
+ 1) / sizeof(WCHAR
) - 1] = 0;
2127 ok( !memcmp( data
, bufferW
, len
),
2128 "%u: wrong data %s\n", i
, wine_dbgstr_wn( data
, (len
+ 1) / sizeof(WCHAR
) ));
2129 data
= GetClipboardData( CF_TEXT
);
2130 if (test_data
[i
].len
>= sizeof(WCHAR
))
2132 ok( data
!= 0, "%u: could not get data\n", i
);
2133 len
= GlobalSize( data
);
2134 len2
= WideCharToMultiByte( CP_ACP
, 0, bufferW
, test_data
[i
].len
/ sizeof(WCHAR
),
2135 bufferA
, 12, NULL
, NULL
);
2136 bufferA
[len2
- 1] = 0;
2137 ok( len
== len2
, "%u: wrong size %u / %u\n", i
, len
, len2
);
2138 ok( !memcmp( data
, bufferA
, len
), "%u: wrong data %.*s\n", i
, len
, (char *)data
);
2142 ok( !data
, "%u: got data for empty string\n", i
);
2143 ok( IsClipboardFormatAvailable( CF_TEXT
), "%u: text not available\n", i
);
2146 r
= CloseClipboard();
2147 ok( r
, "gle %d\n", GetLastError() );
2150 START_TEST(clipboard
)
2153 int argc
= winetest_get_mainargs( &argv
);
2154 HMODULE mod
= GetModuleHandleA( "user32" );
2157 pAddClipboardFormatListener
= (void *)GetProcAddress( mod
, "AddClipboardFormatListener" );
2158 pRemoveClipboardFormatListener
= (void *)GetProcAddress( mod
, "RemoveClipboardFormatListener" );
2159 pGetUpdatedClipboardFormats
= (void *)GetProcAddress( mod
, "GetUpdatedClipboardFormats" );
2161 if (argc
== 4 && !strcmp( argv
[2], "set_clipboard_data" ))
2163 set_clipboard_data_process( atoi( argv
[3] ));
2166 if (argc
== 4 && !strcmp( argv
[2], "grab_clipboard" ))
2168 grab_clipboard_process( atoi( argv
[3] ));
2171 if (argc
== 4 && !strcmp( argv
[2], "handles" ))
2173 test_handles_process( argv
[3] );
2176 if (argc
== 4 && !strcmp( argv
[2], "handles_open" ))
2178 test_handles_process_open( argv
[3] );
2181 if (argc
== 4 && !strcmp( argv
[2], "handles_dib" ))
2183 test_handles_process_dib( argv
[3] );
2186 if (argc
== 4 && !strcmp( argv
[2], "string_data" ))
2188 test_string_data_process( atoi( argv
[3] ));
2191 if (argc
== 3 && !strcmp( argv
[2], "get_clipboard_data" ))
2193 get_clipboard_data_process( );
2197 test_RegisterClipboardFormatA();
2198 test_ClipboardOwner();
2201 test_data_handles();
2202 test_GetUpdatedClipboardFormats();