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
21 #include "wine/test.h"
27 static BOOL (WINAPI
*pAddClipboardFormatListener
)(HWND hwnd
);
28 static DWORD (WINAPI
*pGetClipboardSequenceNumber
)(void);
30 static int thread_from_line
;
32 static DWORD WINAPI
open_clipboard_thread(LPVOID arg
)
35 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
39 static DWORD WINAPI
empty_clipboard_thread(LPVOID arg
)
41 SetLastError( 0xdeadbeef );
42 ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line
);
43 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
44 thread_from_line
, GetLastError());
48 static DWORD WINAPI
open_and_empty_clipboard_thread(LPVOID arg
)
51 ok(OpenClipboard(hWnd
), "%u: OpenClipboard failed\n", thread_from_line
);
52 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line
);
56 static DWORD WINAPI
set_clipboard_data_thread(LPVOID arg
)
61 SetLastError( 0xdeadbeef );
62 if (GetClipboardOwner() == hwnd
)
64 SetClipboardData( CF_WAVE
, 0 );
65 todo_wine
ok( IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData failed\n", thread_from_line
);
66 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
67 ok( ret
!= 0, "%u: SetClipboardData failed err %u\n", thread_from_line
, GetLastError() );
71 SetClipboardData( CF_WAVE
, 0 );
72 todo_wine
ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
73 thread_from_line
, GetLastError());
74 ok( !IsClipboardFormatAvailable( CF_WAVE
), "%u: SetClipboardData succeeded\n", thread_from_line
);
75 ret
= SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 ));
76 todo_wine
ok( !ret
, "%u: SetClipboardData succeeded\n", thread_from_line
);
77 todo_wine
ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "%u: wrong error %u\n",
78 thread_from_line
, GetLastError());
83 static void run_thread( LPTHREAD_START_ROUTINE func
, void *arg
, int line
)
88 thread_from_line
= line
;
89 thread
= CreateThread(NULL
, 0, func
, arg
, 0, NULL
);
90 ok(thread
!= NULL
, "%u: CreateThread failed with error %d\n", line
, GetLastError());
93 ret
= MsgWaitForMultipleObjectsEx( 1, &thread
, 1000, QS_ALLINPUT
, 0 );
94 if (ret
== WAIT_OBJECT_0
+ 1)
97 while (PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageW( &msg
);
101 ok(ret
== WAIT_OBJECT_0
, "%u: expected WAIT_OBJECT_0, got %u\n", line
, ret
);
105 static void test_ClipboardOwner(void)
110 SetLastError(0xdeadbeef);
111 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
112 "could not perform clipboard test: clipboard already owned\n");
114 hWnd1
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
115 0, 0, 10, 10, 0, 0, 0, NULL
);
116 ok(hWnd1
!= 0, "CreateWindowExA error %d\n", GetLastError());
117 trace("hWnd1 = %p\n", hWnd1
);
119 hWnd2
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
120 0, 0, 10, 10, 0, 0, 0, NULL
);
121 ok(hWnd2
!= 0, "CreateWindowExA error %d\n", GetLastError());
122 trace("hWnd2 = %p\n", hWnd2
);
124 SetLastError(0xdeadbeef);
125 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
126 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
127 "wrong error %u\n", GetLastError());
129 ok(OpenClipboard(0), "OpenClipboard failed\n");
130 ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
131 ok(!OpenClipboard(hWnd1
), "OpenClipboard should fail since clipboard already opened\n");
132 ok(OpenClipboard(0), "OpenClipboard again failed\n");
133 ret
= CloseClipboard();
134 ok( ret
, "CloseClipboard error %d\n", GetLastError());
136 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
137 run_thread( open_clipboard_thread
, hWnd1
, __LINE__
);
138 run_thread( empty_clipboard_thread
, 0, __LINE__
);
139 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
140 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
141 ok(OpenClipboard(hWnd1
), "OpenClipboard failed\n");
143 SetLastError(0xdeadbeef);
144 ret
= OpenClipboard(hWnd2
);
145 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
146 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
148 SetLastError(0xdeadbeef);
149 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
150 ret
= EmptyClipboard();
151 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
152 ok(GetClipboardOwner() == hWnd1
, "clipboard should be owned by %p, not by %p\n", hWnd1
, GetClipboardOwner());
153 run_thread( empty_clipboard_thread
, 0, __LINE__
);
154 run_thread( set_clipboard_data_thread
, hWnd1
, __LINE__
);
156 SetLastError(0xdeadbeef);
157 ret
= OpenClipboard(hWnd2
);
158 ok(!ret
&& (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED
),
159 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
161 ret
= CloseClipboard();
162 ok( ret
, "CloseClipboard error %d\n", GetLastError());
163 ok(GetClipboardOwner() == hWnd1
, "clipboard should still be owned\n");
165 /* any window will do, even from a different process */
166 ret
= OpenClipboard( GetDesktopWindow() );
167 ok( ret
, "OpenClipboard error %d\n", GetLastError());
168 ret
= EmptyClipboard();
169 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
170 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
171 GetClipboardOwner(), GetDesktopWindow() );
172 run_thread( set_clipboard_data_thread
, GetDesktopWindow(), __LINE__
);
173 ret
= CloseClipboard();
174 ok( ret
, "CloseClipboard error %d\n", GetLastError());
176 ret
= OpenClipboard( hWnd1
);
177 ok( ret
, "OpenClipboard error %d\n", GetLastError());
178 ret
= EmptyClipboard();
179 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
180 ok( GetClipboardOwner() == hWnd1
, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1
);
181 ret
= CloseClipboard();
182 ok( ret
, "CloseClipboard error %d\n", GetLastError());
184 ret
= DestroyWindow(hWnd1
);
185 ok( ret
, "DestroyWindow error %d\n", GetLastError());
186 ret
= DestroyWindow(hWnd2
);
187 ok( ret
, "DestroyWindow error %d\n", GetLastError());
188 SetLastError(0xdeadbeef);
189 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
191 ret
= OpenClipboard( 0 );
192 ok( ret
, "OpenClipboard error %d\n", GetLastError());
193 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
194 ret
= CloseClipboard();
195 ok( ret
, "CloseClipboard error %d\n", GetLastError());
197 run_thread( open_and_empty_clipboard_thread
, 0, __LINE__
);
199 ret
= OpenClipboard( 0 );
200 ok( ret
, "OpenClipboard error %d\n", GetLastError());
201 run_thread( set_clipboard_data_thread
, 0, __LINE__
);
202 ret
= EmptyClipboard();
203 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
204 ret
= CloseClipboard();
205 ok( ret
, "CloseClipboard error %d\n", GetLastError());
207 SetLastError( 0xdeadbeef );
208 todo_wine
ok( !SetClipboardData( CF_WAVE
, GlobalAlloc( GMEM_DDESHARE
| GMEM_ZEROINIT
, 100 )),
209 "SetClipboardData succeeded\n" );
210 todo_wine
ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError() );
211 todo_wine
ok( !IsClipboardFormatAvailable( CF_WAVE
), "SetClipboardData succeeded\n" );
215 static void test_RegisterClipboardFormatA(void)
218 UINT format_id
, format_id2
;
224 format_id
= RegisterClipboardFormatA("my_cool_clipboard_format");
225 ok(format_id
> 0xc000 && format_id
< 0xffff, "invalid clipboard format id %04x\n", format_id
);
227 format_id2
= RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
228 ok(format_id2
== format_id
, "invalid clipboard format id %04x\n", format_id2
);
230 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
231 ok(len
== lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len
);
232 ok(!lstrcmpA(buf
, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf
);
234 lstrcpyA(buf
, "foo");
235 SetLastError(0xdeadbeef);
236 len
= GetAtomNameA((ATOM
)format_id
, buf
, 256);
237 ok(len
== 0, "GetAtomNameA should fail\n");
238 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
242 lstrcpyA(buf
, "foo");
243 SetLastError(0xdeadbeef);
244 len
= GlobalGetAtomNameA((ATOM
)format_id
, buf
, 256);
245 ok(len
== 0, "GlobalGetAtomNameA should fail\n");
246 ok(GetLastError() == ERROR_INVALID_HANDLE
, "err %d\n", GetLastError());
249 SetLastError(0xdeadbeef);
250 atom_id
= FindAtomA("my_cool_clipboard_format");
251 ok(atom_id
== 0, "FindAtomA should fail\n");
252 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
256 /* this relies on the clipboard and global atom table being different */
257 SetLastError(0xdeadbeef);
258 atom_id
= GlobalFindAtomA("my_cool_clipboard_format");
259 ok(atom_id
== 0, "GlobalFindAtomA should fail\n");
260 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "err %d\n", GetLastError());
263 for (format_id
= 0; format_id
< 0xffff; format_id
++)
265 SetLastError(0xdeadbeef);
266 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
268 if (format_id
< 0xc000)
269 ok(!len
, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len
, buf
);
270 else if (len
&& winetest_debug
> 1)
271 trace("%04x: %s\n", format_id
, len
? buf
: "");
274 ret
= OpenClipboard(0);
275 ok( ret
, "OpenClipboard error %d\n", GetLastError());
277 /* try some invalid/unregistered formats */
278 SetLastError( 0xdeadbeef );
279 handle
= SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
280 ok( !handle
, "SetClipboardData succeeded\n" );
281 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
, "wrong error %u\n", GetLastError());
282 handle
= SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
283 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
284 handle
= SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
285 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
286 handle
= SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE
| GMEM_MOVEABLE
, 1 ));
287 ok( handle
!= 0, "SetClipboardData failed err %d\n", GetLastError());
289 ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
290 ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
291 ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
292 ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
293 ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
294 ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
296 trace("# of formats available: %d\n", CountClipboardFormats());
299 while ((format_id
= EnumClipboardFormats(format_id
)))
301 ok(IsClipboardFormatAvailable(format_id
), "format %04x was listed as available\n", format_id
);
302 len
= GetClipboardFormatNameA(format_id
, buf
, 256);
303 trace("%04x: %s\n", format_id
, len
? buf
: "");
306 ret
= EmptyClipboard();
307 ok( ret
, "EmptyClipboard error %d\n", GetLastError());
308 ret
=CloseClipboard();
309 ok( ret
, "CloseClipboard error %d\n", GetLastError());
311 if (CountClipboardFormats())
313 SetLastError(0xdeadbeef);
314 ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
315 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
,
316 "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError());
319 SetLastError(0xdeadbeef);
320 ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
321 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN
|| broken(GetLastError() == 0xdeadbeef), /* wow64 */
322 "Wrong error %u\n", GetLastError());
324 format_id
= RegisterClipboardFormatA("#1234");
325 ok(format_id
== 1234, "invalid clipboard format id %04x\n", format_id
);
328 static HGLOBAL
create_text(void)
330 HGLOBAL h
= GlobalAlloc(GMEM_DDESHARE
|GMEM_MOVEABLE
, 5);
331 char *p
= GlobalLock(h
);
337 static HENHMETAFILE
create_emf(void)
339 const RECT rect
= {0, 0, 100, 100};
340 HDC hdc
= CreateEnhMetaFileA(NULL
, NULL
, &rect
, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
341 ExtTextOutA(hdc
, 0, 0, ETO_OPAQUE
, &rect
, "Test String", strlen("Test String"), NULL
);
342 return CloseEnhMetaFile(hdc
);
345 static void test_synthesized(void)
353 htext
= create_text();
356 r
= OpenClipboard(NULL
);
357 ok(r
, "gle %d\n", GetLastError());
358 r
= EmptyClipboard();
359 ok(r
, "gle %d\n", GetLastError());
360 h
= SetClipboardData(CF_TEXT
, htext
);
361 ok(h
== htext
, "got %p\n", h
);
362 h
= SetClipboardData(CF_ENHMETAFILE
, emf
);
363 ok(h
== emf
, "got %p\n", h
);
364 r
= CloseClipboard();
365 ok(r
, "gle %d\n", GetLastError());
367 r
= OpenClipboard(NULL
);
368 ok(r
, "gle %d\n", GetLastError());
369 cf
= EnumClipboardFormats(0);
370 ok(cf
== CF_TEXT
, "cf %08x\n", cf
);
371 data
= GetClipboardData(cf
);
372 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
374 cf
= EnumClipboardFormats(cf
);
375 ok(cf
== CF_ENHMETAFILE
, "cf %08x\n", cf
);
376 data
= GetClipboardData(cf
);
377 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
379 cf
= EnumClipboardFormats(cf
);
380 todo_wine
ok(cf
== CF_LOCALE
, "cf %08x\n", cf
);
382 cf
= EnumClipboardFormats(cf
);
383 ok(cf
== CF_OEMTEXT
, "cf %08x\n", cf
);
384 data
= GetClipboardData(cf
);
385 ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
387 cf
= EnumClipboardFormats(cf
);
388 ok(cf
== CF_UNICODETEXT
, "cf %08x\n", cf
);
390 cf
= EnumClipboardFormats(cf
);
391 ok(cf
== CF_METAFILEPICT
, "cf %08x\n", cf
);
392 data
= GetClipboardData(cf
);
393 todo_wine
ok(data
!= NULL
, "couldn't get data, cf %08x\n", cf
);
395 cf
= EnumClipboardFormats(cf
);
396 ok(cf
== 0, "cf %08x\n", cf
);
398 r
= EmptyClipboard();
399 ok(r
, "gle %d\n", GetLastError());
401 r
= CloseClipboard();
402 ok(r
, "gle %d\n", GetLastError());
405 static CRITICAL_SECTION clipboard_cs
;
406 static HWND next_wnd
;
407 static LRESULT CALLBACK
clipboard_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
409 static UINT wm_drawclipboard
;
410 static UINT wm_clipboardupdate
;
411 static UINT wm_destroyclipboard
;
415 case WM_DRAWCLIPBOARD
:
416 EnterCriticalSection(&clipboard_cs
);
418 LeaveCriticalSection(&clipboard_cs
);
420 case WM_CHANGECBCHAIN
:
421 if (next_wnd
== (HWND
)wp
)
424 SendMessageA(next_wnd
, msg
, wp
, lp
);
426 case WM_DESTROYCLIPBOARD
:
427 wm_destroyclipboard
++;
428 ok( GetClipboardOwner() == hwnd
, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
430 case WM_CLIPBOARDUPDATE
:
431 wm_clipboardupdate
++;
434 ChangeClipboardChain(hwnd
, next_wnd
);
438 ret
= wm_drawclipboard
;
439 wm_drawclipboard
= 0;
442 ret
= wm_clipboardupdate
;
443 wm_clipboardupdate
= 0;
446 ret
= wm_destroyclipboard
;
447 wm_destroyclipboard
= 0;
451 return DefWindowProcA(hwnd
, msg
, wp
, lp
);
454 static DWORD WINAPI
clipboard_thread(void *param
)
459 UINT count
, old_seq
= 0, seq
;
461 if (pGetClipboardSequenceNumber
) old_seq
= pGetClipboardSequenceNumber();
463 EnterCriticalSection(&clipboard_cs
);
464 SetLastError(0xdeadbeef);
465 next_wnd
= SetClipboardViewer(win
);
466 ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
467 LeaveCriticalSection(&clipboard_cs
);
468 if (pAddClipboardFormatListener
)
470 r
= pAddClipboardFormatListener(win
);
471 ok( r
, "AddClipboardFormatListener failed err %d\n", GetLastError());
474 if (pGetClipboardSequenceNumber
)
476 seq
= pGetClipboardSequenceNumber();
477 ok( seq
== old_seq
, "sequence changed\n" );
479 count
= SendMessageA( win
, WM_USER
+ 1, 0, 0 );
480 ok( count
, "WM_DRAWCLIPBOARD received\n" );
481 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
482 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
484 r
= OpenClipboard(win
);
485 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
487 if (pGetClipboardSequenceNumber
)
489 seq
= pGetClipboardSequenceNumber();
490 ok( seq
== old_seq
, "sequence changed\n" );
492 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
493 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
494 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
495 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
497 r
= EmptyClipboard();
498 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
500 if (pGetClipboardSequenceNumber
)
502 seq
= pGetClipboardSequenceNumber();
503 ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
506 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
507 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
508 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
509 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
510 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
511 ok( !count
, "WM_DESTROYCLIPBOARD received\n" );
513 r
= EmptyClipboard();
514 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
515 /* sequence changes again, even though it was already empty */
516 if (pGetClipboardSequenceNumber
)
518 seq
= pGetClipboardSequenceNumber();
519 ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
522 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
523 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
524 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
525 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
526 count
= SendMessageA( win
, WM_USER
+3, 0, 0 );
527 ok( count
, "WM_DESTROYCLIPBOARD not received\n" );
529 handle
= SetClipboardData( CF_TEXT
, create_text() );
530 ok(handle
!= 0, "SetClipboardData failed: %d\n", GetLastError());
532 if (pGetClipboardSequenceNumber
)
534 seq
= pGetClipboardSequenceNumber();
535 todo_wine
ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
538 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
539 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
540 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
541 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
543 SetClipboardData( CF_UNICODETEXT
, 0 );
545 if (pGetClipboardSequenceNumber
)
547 seq
= pGetClipboardSequenceNumber();
548 todo_wine
ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
551 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
552 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
553 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
554 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
556 SetClipboardData( CF_UNICODETEXT
, 0 ); /* same data again */
558 if (pGetClipboardSequenceNumber
)
560 seq
= pGetClipboardSequenceNumber();
561 todo_wine
ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
564 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
565 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
566 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
567 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
569 EnterCriticalSection(&clipboard_cs
);
570 r
= CloseClipboard();
571 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
572 LeaveCriticalSection(&clipboard_cs
);
574 if (pGetClipboardSequenceNumber
)
576 seq
= pGetClipboardSequenceNumber();
577 ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
580 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
581 ok( count
, "WM_DRAWCLIPBOARD not received\n" );
582 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
583 todo_wine
ok( count
|| broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
585 r
= OpenClipboard(win
);
586 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
588 if (pGetClipboardSequenceNumber
)
590 seq
= pGetClipboardSequenceNumber();
591 ok( seq
== old_seq
, "sequence changed\n" );
593 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
594 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
595 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
596 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
598 SetClipboardData( CF_WAVE
, 0 );
599 if (pGetClipboardSequenceNumber
)
601 seq
= pGetClipboardSequenceNumber();
602 todo_wine
ok( (int)(seq
- old_seq
) > 0, "sequence unchanged\n" );
605 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
606 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
607 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
608 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
610 r
= CloseClipboard();
611 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
612 if (pGetClipboardSequenceNumber
)
614 /* no synthesized format, so CloseClipboard doesn't change the sequence */
615 seq
= pGetClipboardSequenceNumber();
616 todo_wine
ok( seq
== old_seq
, "sequence changed\n" );
619 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
620 ok( count
, "WM_DRAWCLIPBOARD not received\n" );
621 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
622 todo_wine
ok( count
|| broken(!pAddClipboardFormatListener
), "WM_CLIPBOARDUPDATE not received\n" );
624 r
= OpenClipboard(win
);
625 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
626 r
= CloseClipboard();
627 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
628 /* nothing changed */
629 if (pGetClipboardSequenceNumber
)
631 seq
= pGetClipboardSequenceNumber();
632 ok( seq
== old_seq
, "sequence changed\n" );
634 count
= SendMessageA( win
, WM_USER
+1, 0, 0 );
635 ok( !count
, "WM_DRAWCLIPBOARD received\n" );
636 count
= SendMessageA( win
, WM_USER
+2, 0, 0 );
637 ok( !count
, "WM_CLIPBOARDUPDATE received\n" );
639 r
= OpenClipboard(0);
640 ok(r
, "OpenClipboard failed: %d\n", GetLastError());
641 r
= EmptyClipboard();
642 ok(r
, "EmptyClipboard failed: %d\n", GetLastError());
643 r
= CloseClipboard();
644 ok(r
, "CloseClipboard failed: %d\n", GetLastError());
646 r
= PostMessageA(win
, WM_USER
, 0, 0);
647 ok(r
, "PostMessage failed: %d\n", GetLastError());
651 static void test_messages(void)
659 InitializeCriticalSection(&clipboard_cs
);
661 memset(&cls
, 0, sizeof(cls
));
662 cls
.lpfnWndProc
= clipboard_wnd_proc
;
663 cls
.hInstance
= GetModuleHandleA(NULL
);
664 cls
.lpszClassName
= "clipboard_test";
665 RegisterClassA(&cls
);
667 win
= CreateWindowA("clipboard_test", NULL
, 0, 0, 0, 0, 0, NULL
, 0, NULL
, 0);
668 ok(win
!= NULL
, "CreateWindow failed: %d\n", GetLastError());
670 thread
= CreateThread(NULL
, 0, clipboard_thread
, (void*)win
, 0, &tid
);
671 ok(thread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
673 while(GetMessageA(&msg
, NULL
, 0, 0)) {
674 TranslateMessage(&msg
);
675 DispatchMessageA(&msg
);
678 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
681 UnregisterClassA("clipboard_test", GetModuleHandleA(NULL
));
682 DeleteCriticalSection(&clipboard_cs
);
685 START_TEST(clipboard
)
687 HMODULE mod
= GetModuleHandleA( "user32" );
689 pAddClipboardFormatListener
= (void *)GetProcAddress( mod
, "AddClipboardFormatListener" );
690 pGetClipboardSequenceNumber
= (void *)GetProcAddress( mod
, "GetClipboardSequenceNumber" );
692 test_RegisterClipboardFormatA();
693 test_ClipboardOwner();