ReactOS 0.4.16-dev-2491-g3dc6630
clipboard.c
Go to the documentation of this file.
1/*
2 * Unit test suite for clipboard functions.
3 *
4 * Copyright 2002 Dmitry Timoshkov
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <stdio.h>
22#include "wine/test.h"
23#include "winbase.h"
24#include "winerror.h"
25#include "wingdi.h"
26#include "winuser.h"
27#include "winnls.h"
28
29static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd);
30static BOOL (WINAPI *pRemoveClipboardFormatListener)(HWND hwnd);
31static BOOL (WINAPI *pGetUpdatedClipboardFormats)( UINT *formats, UINT count, UINT *out_count );
32static HGLOBAL (WINAPI *pGlobalFree)(HGLOBAL);
33
35static char *argv0;
36
37#define open_clipboard(hwnd) open_clipboard_(__LINE__, hwnd)
39{
41 while (1)
42 {
45 return ret;
46 if (GetTickCount() - start > 100)
47 {
48 char classname[256];
49 DWORD le = GetLastError();
50 HWND clipwnd = GetOpenClipboardWindow();
51 /* Provide a hint as to the source of interference:
52 * - The class name would typically be CLIPBRDWNDCLASS if the
53 * clipboard was opened by a Windows application using the
54 * ole32 API.
55 * - And it would be __wine_clipboard_manager if it was opened in
56 * response to a native application.
57 */
59 trace_(__FILE__, line)("%p (%s) opened the clipboard\n", clipwnd, classname);
60 SetLastError(le);
61 return ret;
62 }
63 Sleep(15);
64 }
65}
66
67#define has_no_open_wnd() has_no_open_wnd_(__LINE__)
69{
71 DWORD le = GetLastError();
72 while (1)
73 {
74 HWND clipwnd = GetOpenClipboardWindow();
75 if (!clipwnd) return TRUE;
76 if (GetTickCount() - start > 100)
77 {
78 char classname[256];
79 le = GetLastError();
80 /* See open_clipboard() */
82 trace_(__FILE__, line)("%p (%s) opened the clipboard\n", clipwnd, classname);
83 SetLastError(le);
84 return FALSE;
85 }
86 Sleep(15);
87 SetLastError(le);
88 }
89}
90
92{
93 HWND hWnd = arg;
94 ok(open_clipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line);
95 return 0;
96}
97
99{
100 SetLastError( 0xdeadbeef );
101 ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line );
102 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %lu\n",
104 return 0;
105}
106
108{
109 HWND hWnd = arg;
110 ok(open_clipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line);
111 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line );
112 return 0;
113}
114
116{
117 HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
118 ok(open_clipboard(hwnd), "%u: OpenClipboard failed\n", thread_from_line);
119 ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line );
120 return 0;
121}
122
124{
125 HWND hwnd = arg;
126 HANDLE ret;
127
128 SetLastError( 0xdeadbeef );
129 if (GetClipboardOwner() == hwnd)
130 {
132 ok( IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData failed\n", thread_from_line );
134 ok( ret != 0, "%u: SetClipboardData failed err %lu\n", thread_from_line, GetLastError() );
135 SetLastError( 0xdeadbeef );
137 ok( !ret, "%u: GetClipboardData succeeded\n", thread_from_line );
138 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %lu\n",
140 }
141 else
142 {
144 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %lu\n",
146 ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line );
148 ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line );
149 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %lu\n",
151 }
152 return 0;
153}
154
156{
157 HANDLE ret;
158
159 winetest_push_context("process %u", arg);
160 SetLastError( 0xdeadbeef );
161 if (arg)
162 {
163 ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
165 ok( ret != 0, "SetClipboardData failed err %lu\n", GetLastError() );
166 }
167 else
168 {
170 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %lu\n",
171 GetLastError());
172 ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" );
174 ok( !ret, "SetClipboardData succeeded\n" );
175 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %lu\n",
176 GetLastError());
177 }
179}
180
181static void grab_clipboard_process( int arg )
182{
183 BOOL ret;
184
185 SetLastError( 0xdeadbeef );
186 ret = open_clipboard( 0 );
187 ok( ret, "OpenClipboard failed\n" );
189 ok( ret, "EmptyClipboard failed\n" );
190 if (arg)
191 {
193 ok( ret != 0, "process %u: SetClipboardData failed err %lu\n", arg, GetLastError() );
194 }
195}
196
198{
199 DWORD ret;
201
203 thread = CreateThread(NULL, 0, func, arg, 0, NULL);
204 ok(thread != NULL, "%u: CreateThread failed with error %ld\n", line, GetLastError());
205 for (;;)
206 {
208 if (ret == WAIT_OBJECT_0 + 1)
209 {
210 MSG msg;
211 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
212 }
213 else break;
214 }
215 ok(ret == WAIT_OBJECT_0, "%u: expected WAIT_OBJECT_0, got %lu\n", line, ret);
217}
218
219static void run_process( const char *args )
220{
221 char cmd[MAX_PATH];
224
225 sprintf( cmd, "%s clipboard %s", argv0, args );
226 memset( &startup, 0, sizeof(startup) );
227 startup.cb = sizeof(startup);
229 "CreateProcess %s failed\n", cmd );
230
231 wait_child_process( info.hProcess );
232 CloseHandle( info.hProcess );
233 CloseHandle( info.hThread );
234}
235
238{
239 static int wm_renderallformats;
240 static int wm_drawclipboard;
241 static int seqno;
242 DWORD msg_flags = InSendMessageEx( NULL );
243
244 if (!seqno) seqno = GetClipboardSequenceNumber();
245
246 trace( "%p msg %04x\n", hwnd, msg );
247 if (!wm_renderallformats)
248 {
249 ok( GetClipboardOwner() == hwnd, "%04x: wrong owner %p/%p\n", msg, GetClipboardOwner(), hwnd );
250 ok( seqno == GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg );
251 }
252 else
253 {
254 ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg, GetClipboardOwner() );
255 ok( seqno + 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg );
256 }
257 ok( GetClipboardViewer() == hwnd, "%04x: wrong viewer %p/%p\n", msg, GetClipboardViewer(), hwnd );
258 ok( GetOpenClipboardWindow() == hwnd, "%04x: wrong open win %p/%p\n",
260
261 switch (msg)
262 {
263 case WM_DESTROY:
264 ok( wm_renderallformats, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
265 ok( wm_drawclipboard, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
266 break;
267 case WM_DRAWCLIPBOARD:
268 ok( msg_flags == ISMEX_NOSEND, "WM_DRAWCLIPBOARD wrong flags %lx\n", msg_flags );
270 break;
272 ok( msg_flags == ISMEX_NOSEND, "WM_RENDERALLFORMATS wrong flags %lx\n", msg_flags );
273 wm_renderallformats++;
274 break;
275 }
276 return old_proc( hwnd, msg, wp, lp );
277}
278
279static void test_ClipboardOwner(void)
280{
282 BOOL ret;
283
284 SetLastError(0xdeadbeef);
285 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
286 "could not perform clipboard test: clipboard already owned\n");
287
288 hWnd1 = CreateWindowExA(0, "static", NULL, WS_POPUP,
289 0, 0, 10, 10, 0, 0, 0, NULL);
290 ok(hWnd1 != 0, "CreateWindowExA error %ld\n", GetLastError());
291 trace("hWnd1 = %p\n", hWnd1);
292
293 hWnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP,
294 0, 0, 10, 10, 0, 0, 0, NULL);
295 ok(hWnd2 != 0, "CreateWindowExA error %ld\n", GetLastError());
296 trace("hWnd2 = %p\n", hWnd2);
297
298 SetLastError(0xdeadbeef);
299 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
300 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */
301 "wrong error %lu\n", GetLastError());
302
303 ok(open_clipboard(0), "OpenClipboard failed\n");
304 ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
305 ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n");
306 ok(open_clipboard(0), "OpenClipboard again failed\n");
308 ok( ret, "CloseClipboard error %ld\n", GetLastError());
309
310 ok(open_clipboard(hWnd1), "OpenClipboard failed\n");
312 run_thread( empty_clipboard_thread, 0, __LINE__ );
314 ok( !IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE available\n" );
315 ok( !GetClipboardData( CF_WAVE ), "CF_WAVE data available\n" );
316 run_process( "set_clipboard_data 0" );
317 ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
318 ok(open_clipboard(hWnd1), "OpenClipboard failed\n");
319
320 SetLastError(0xdeadbeef);
322 ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
323 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %ld\n", GetLastError());
324
325 SetLastError(0xdeadbeef);
326 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
328 ok( ret, "EmptyClipboard error %ld\n", GetLastError());
329 ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner());
330 run_thread( empty_clipboard_thread, 0, __LINE__ );
332 ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
333 ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
334 run_process( "set_clipboard_data 1" );
335
336 SetLastError(0xdeadbeef);
338 ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
339 "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %ld\n", GetLastError());
340
342 ok( ret, "CloseClipboard error %ld\n", GetLastError());
343 ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n");
344
345 /* any window will do, even from a different process */
347 ok( ret, "OpenClipboard error %ld\n", GetLastError());
349 ok( ret, "EmptyClipboard error %ld\n", GetLastError());
350 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
353 ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
354 ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
355 run_process( "set_clipboard_data 2" );
357 ok( ret, "CloseClipboard error %ld\n", GetLastError());
358
360 ok( ret, "OpenClipboard error %ld\n", GetLastError());
362 ok( ret, "EmptyClipboard error %ld\n", GetLastError());
365 ok( GetClipboardOwner() == hWnd1, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1 );
366 ok( GetClipboardViewer() == hWnd1, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1 );
367 ok( GetOpenClipboardWindow() == hWnd1, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1 );
368 ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
369
372 ok( ret, "DestroyWindow error %ld\n", GetLastError());
374 ok( ret, "DestroyWindow error %ld\n", GetLastError());
375 SetLastError(0xdeadbeef);
376 ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
377 ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n");
378 ok( has_no_open_wnd() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n");
379 ok( !IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE available\n" );
380
381 SetLastError( 0xdeadbeef );
383 ok( !ret, "CloseClipboard succeeded\n" );
384 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %lu\n", GetLastError() );
385
386 ret = open_clipboard( 0 );
387 ok( ret, "OpenClipboard error %ld\n", GetLastError());
389 ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
390 ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
391 run_process( "set_clipboard_data 3" );
393 ok( ret, "CloseClipboard error %ld\n", GetLastError());
394
396 ok( has_no_open_wnd(), "wrong open window\n" );
397 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
398
399 ret = open_clipboard( 0 );
400 ok( ret, "OpenClipboard error %ld\n", GetLastError());
402 ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
403 ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
404 run_process( "set_clipboard_data 4" );
406 ok( ret, "EmptyClipboard error %ld\n", GetLastError());
408 ok( ret, "CloseClipboard error %ld\n", GetLastError());
409
410 SetLastError( 0xdeadbeef );
412 "SetClipboardData succeeded\n" );
413 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %lu\n", GetLastError() );
414 ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" );
415
417 ok( has_no_open_wnd(), "wrong open window\n" );
418 ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n",
420
422 ok( has_no_open_wnd(), "wrong open window\n" );
423 ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
424}
425
427{
428 ATOM atom_id;
429 UINT format_id, format_id2;
430 char buf[256];
431 int len;
432 BOOL ret;
434
435 format_id = RegisterClipboardFormatA("my_cool_clipboard_format");
436 ok(format_id > 0xc000 && format_id < 0xffff, "invalid clipboard format id %04x\n", format_id);
437
438 format_id2 = RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
439 ok(format_id2 == format_id, "invalid clipboard format id %04x\n", format_id2);
440
442 ok(len == lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len);
443 ok(!lstrcmpA(buf, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf);
444
446 ok(len == 0, "wrong format name length %d\n", len);
447
448 lstrcpyA(buf, "foo");
449 SetLastError(0xdeadbeef);
451 ok(len == 0 || lstrcmpA(buf, "my_cool_clipboard_format") != 0,
452 "format_id should not be a valid local atom\n");
454 "err %ld\n", GetLastError());
455
456 lstrcpyA(buf, "foo");
457 SetLastError(0xdeadbeef);
459 todo_wine ok(len == 0 || lstrcmpA(buf, "my_cool_clipboard_format") != 0,
460 "format_id should not be a valid global atom\n");
462 "err %ld\n", GetLastError());
463
464 SetLastError(0xdeadbeef);
465 atom_id = FindAtomA("my_cool_clipboard_format");
466 ok(atom_id == 0, "FindAtomA should fail, but it returned %x (format_id=%x)\n", atom_id, format_id);
467 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %ld\n", GetLastError());
468
470 {
471 /* this relies on the clipboard and global atom table being different */
472 SetLastError(0xdeadbeef);
473 atom_id = GlobalFindAtomA("my_cool_clipboard_format");
474 ok(atom_id == 0, "GlobalFindAtomA should fail, but it returned %x (format_id=%x)\n", atom_id, format_id);
475 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %ld\n", GetLastError());
476 }
477
478 for (format_id = 0; format_id < 0x10fff; format_id++)
479 {
480 SetLastError(0xdeadbeef);
482
483 if (format_id < 0xc000 || format_id > 0xffff)
484 ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf);
485 else if (len && winetest_debug > 1)
486 trace("%04x: %s\n", format_id, len ? buf : "");
487 }
488
489 ret = open_clipboard(0);
490 ok( ret, "OpenClipboard error %ld\n", GetLastError());
491
492 /* try some invalid/unregistered formats */
493 SetLastError( 0xdeadbeef );
495 ok( !handle, "SetClipboardData succeeded\n" );
496 ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %lu\n", GetLastError());
498 ok( handle != 0, "SetClipboardData failed err %ld\n", GetLastError());
500 ok( handle != 0, "SetClipboardData failed err %ld\n", GetLastError());
502 ok( handle != 0, "SetClipboardData failed err %ld\n", GetLastError());
503
504 ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
505 ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
506 ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
507 ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
508 ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
509 ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
510
511 trace("# of formats available: %d\n", CountClipboardFormats());
512
513 format_id = 0;
515 {
516 ok(IsClipboardFormatAvailable(format_id), "format %04x was listed as available\n", format_id);
518 trace("%04x: %s\n", format_id, len ? buf : "");
519 }
520
522 ok( ret, "EmptyClipboard error %ld\n", GetLastError());
524 ok( ret, "CloseClipboard error %ld\n", GetLastError());
525
527 {
528 SetLastError(0xdeadbeef);
529 ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
531 "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %ld\n", GetLastError());
532 }
533
534 SetLastError(0xdeadbeef);
535 ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
536 ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */
537 "Wrong error %lu\n", GetLastError());
538
540 ok(format_id == 1234, "invalid clipboard format id %04x\n", format_id);
541}
542
544{
546 char *p = GlobalLock(h);
547 memcpy(p, "test\0\0\0\0\0", 10);
549 return h;
550}
551
553{
554 static const WCHAR testW[] = {'t','e','s','t',0,0,0,0,0,0};
556 WCHAR *p = GlobalLock(h);
557 memcpy(p, testW, sizeof(testW));
559 return h;
560}
561
563{
564 const RECT rect = {0, 0, 100, 100};
565 METAFILEPICT *pict;
566 HANDLE ret;
567 HMETAFILE mf;
569 ExtTextOutA( hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL );
570 mf = CloseMetaFile( hdc );
571 ret = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(*pict) );
572 pict = GlobalLock( ret );
573 pict->mm = MM_TEXT;
574 pict->xExt = pict->yExt = 100;
575 pict->hMF = mf;
576 GlobalUnlock( ret );
577 return ret;
578}
579
580static HENHMETAFILE create_emf(void)
581{
582 const RECT rect = {0, 0, 100, 100};
583 HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
584 ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
585 return CloseEnhMetaFile(hdc);
586}
587
589{
590 HDC hdc = GetDC( 0 );
592 ReleaseDC( 0, hdc );
593 return CreateBitmap( 10, 10, 1, bpp, NULL );
594}
595
597{
598 HANDLE ret;
600
602 sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD) + 16 * 16 * 4 );
603 hdr = GlobalLock( ret );
604 hdr->biSize = v5 ? sizeof(BITMAPV5HEADER) : sizeof(*hdr);
605 hdr->biWidth = 16;
606 hdr->biHeight = 16;
607 hdr->biPlanes = 1;
608 hdr->biBitCount = 32;
609 hdr->biCompression = BI_RGB;
610 if (v5)
611 {
612 BITMAPV5HEADER *hdr5 = (BITMAPV5HEADER *)hdr;
613 hdr5->bV5RedMask = 0x0000ff;
614 hdr5->bV5GreenMask = 0x00ff00;
615 hdr5->bV5BlueMask = 0xff0000;
616 hdr5->bV5AlphaMask = 0xff000000;
617 }
618 GlobalUnlock( ret );
619 return ret;
620}
621
623{
624 static UINT rendered;
625 UINT ret;
626
627 switch (msg)
628 {
629 case WM_RENDERFORMAT:
630 if (wp < 32) rendered |= (1 << wp);
631 break;
632 case WM_USER:
633 ret = rendered;
634 rendered = 0;
635 return ret;
636 }
637 return DefWindowProcA( hwnd, msg, wp, lp );
638}
639
640static void test_synthesized(void)
641{
642 static const struct test
643 {
644 UINT format;
645 UINT expected[8];
646 } tests[] =
647 {
653/* 5 */ { CF_BITMAP, { CF_BITMAP, CF_DIB, CF_DIBV5 }},
654 { CF_DIB, { CF_DIB, CF_BITMAP, CF_DIBV5 }},
655 { CF_DIBV5, { CF_DIBV5, CF_BITMAP, CF_DIB }},
656 };
657
658 HGLOBAL h, htext;
659 HENHMETAFILE emf;
660 BOOL r;
661 UINT cf, i, j, count, rendered, seq, old_seq;
662 HANDLE data;
663 HWND hwnd;
664
665 hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
667
668 htext = create_textA();
669 emf = create_emf();
670
672 ok(r, "gle %ld\n", GetLastError());
673 r = EmptyClipboard();
674 ok(r, "gle %ld\n", GetLastError());
675 h = SetClipboardData(CF_TEXT, htext);
676 ok(h == htext, "got %p\n", h);
678 ok(h == emf, "got %p\n", h);
679 r = CloseClipboard();
680 ok(r, "gle %ld\n", GetLastError());
681
683 ok( count == 6, "count %u\n", count );
685 ok( r, "CF_TEXT not available err %ld\n", GetLastError());
687 ok( r, "CF_LOCALE not available err %ld\n", GetLastError());
689 ok( r, "CF_OEMTEXT not available err %ld\n", GetLastError());
691 ok( r, "CF_UNICODETEXT not available err %ld\n", GetLastError());
693 ok( r, "CF_ENHMETAFILE not available err %ld\n", GetLastError());
695 ok( r, "CF_METAFILEPICT not available err %ld\n", GetLastError());
696
698 ok(r, "gle %ld\n", GetLastError());
700 ok(cf == CF_TEXT, "cf %08x\n", cf);
702 ok(data != NULL, "couldn't get data, cf %08x\n", cf);
703
705 ok(cf == CF_ENHMETAFILE, "cf %08x\n", cf);
707 ok(data != NULL, "couldn't get data, cf %08x\n", cf);
708
710 ok(cf == CF_LOCALE, "cf %08x\n", cf);
712 ok(data != NULL, "couldn't get data, cf %08x\n", cf);
713
715 ok(cf == CF_OEMTEXT, "cf %08x\n", cf);
717 ok(data != NULL, "couldn't get data, cf %08x\n", cf);
718
720 ok(cf == CF_UNICODETEXT, "cf %08x\n", cf);
721
723 ok(cf == CF_METAFILEPICT, "cf %08x\n", cf);
725 ok(data != NULL, "couldn't get data, cf %08x\n", cf);
726
728 ok(cf == 0, "cf %08x\n", cf);
729
730 r = EmptyClipboard();
731 ok(r, "gle %ld\n", GetLastError());
732
736 r = CloseClipboard();
737 ok(r, "gle %ld\n", GetLastError());
738
739 r = open_clipboard( NULL );
740 ok(r, "gle %ld\n", GetLastError());
741 SetLastError( 0xdeadbeef );
743 ok( cf == CF_UNICODETEXT, "cf %08x\n", cf );
744 ok( GetLastError() == ERROR_SUCCESS, "wrong error %lu\n", GetLastError() );
745 SetLastError( 0xdeadbeef );
747 ok( cf == CF_TEXT, "cf %08x\n", cf );
748 ok( GetLastError() == ERROR_SUCCESS, "wrong error %lu\n", GetLastError() );
749 SetLastError( 0xdeadbeef );
751 ok( cf == CF_OEMTEXT, "cf %08x\n", cf );
752 ok( GetLastError() == ERROR_SUCCESS, "wrong error %lu\n", GetLastError() );
753 SetLastError( 0xdeadbeef );
755 ok( cf == CF_LOCALE, "cf %08x\n", cf );
756 ok( GetLastError() == ERROR_SUCCESS, "wrong error %lu\n", GetLastError() );
757 SetLastError( 0xdeadbeef );
759 ok( cf == 0, "cf %08x\n", cf );
760 ok( GetLastError() == ERROR_SUCCESS, "wrong error %lu\n", GetLastError() );
761 SetLastError( 0xdeadbeef );
762 cf = EnumClipboardFormats( 0xdead );
763 ok( cf == 0, "cf %08x\n", cf );
764 ok( GetLastError() == ERROR_SUCCESS, "wrong error %lu\n", GetLastError() );
765
766 r = EmptyClipboard();
767 ok(r, "gle %ld\n", GetLastError());
768
769 r = CloseClipboard();
770 ok(r, "gle %ld\n", GetLastError());
771
772 for (i = 0; i < ARRAY_SIZE(tests); i++)
773 {
776 ok(r, "gle %ld\n", GetLastError());
777 r = EmptyClipboard();
778 ok(r, "gle %ld\n", GetLastError());
779
780 switch (tests[i].format)
781 {
782 case CF_TEXT:
783 case CF_OEMTEXT:
785 break;
786 case CF_UNICODETEXT:
788 break;
789 case CF_ENHMETAFILE:
791 break;
792 case CF_METAFILEPICT:
794 break;
795 case CF_BITMAP:
797 break;
798 case CF_DIB:
799 case CF_DIBV5:
801 break;
802 }
803
805 ok( count == 1, "count %u\n", count );
806
807 r = CloseClipboard();
808 ok(r, "gle %ld\n", GetLastError());
809
811 for (j = 0; tests[i].expected[j]; j++)
812 {
814 ok( r, "%04x not available\n", tests[i].expected[j] );
815 }
816 ok( count == j, "count %u instead of %u\n", count, j );
817
818 r = open_clipboard( hwnd );
819 ok(r, "gle %ld\n", GetLastError());
820 cf = 0;
821 for (j = 0; tests[i].expected[j]; j++)
822 {
825 ok(cf == tests[i].expected[j], "got %04x instead of %04x\n",
826 cf, tests[i].expected[j] );
827 if (cf != tests[i].expected[j])
828 {
830 break;
831 }
834 ok(data != NULL ||
835 broken( tests[i].format == CF_DIBV5 && cf == CF_DIB ), /* >= Vista */
836 "couldn't get data, cf %04x err %ld\n", cf, GetLastError());
838 ok(seq == old_seq, "sequence changed (test %d)\n", cf);
839 switch (cf)
840 {
841 case CF_LOCALE:
842 {
843 UINT *ptr = GlobalLock( data );
845 ok( GlobalSize( data ) == sizeof(*ptr), "size %Iu\n", GlobalSize( data ));
846 ok( *ptr == layout ||
848 "CF_LOCALE %04x/%04lx\n", *ptr, layout );
850 break;
851 }
852 case CF_TEXT:
853 case CF_OEMTEXT:
854 ok( GlobalSize( data ) == 10, "wrong len %Id\n", GlobalSize( data ));
855 break;
856 case CF_UNICODETEXT:
857 ok( GlobalSize( data ) == 10 * sizeof(WCHAR), "wrong len %Id\n", GlobalSize( data ));
858 break;
859 }
861 }
862 if (!tests[i].expected[j])
863 {
865 ok(cf == 0, "cf %04x\n", cf);
866 }
867
868 /* now with delayed rendering */
869
870 r = EmptyClipboard();
871 ok(r, "gle %ld\n", GetLastError());
872
873 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
874 ok( !rendered, "formats %08x have been rendered\n", rendered );
875
877 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
878 ok( !rendered, "formats %08x have been rendered\n", rendered );
879
881 ok( count == 1, "count %u\n", count );
882
883 r = CloseClipboard();
884 ok(r, "gle %ld\n", GetLastError());
885 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
886 ok( !rendered, "formats %08x have been rendered\n", rendered );
887
889 for (j = 0; tests[i].expected[j]; j++)
890 {
892 ok( r, "%04x not available\n", tests[i].expected[j] );
893 }
894 ok( count == j, "count %u instead of %u\n", count, j );
895 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
896 ok( !rendered, "formats %08x have been rendered\n", rendered );
897
899 ok(r, "gle %ld\n", GetLastError());
900 cf = 0;
901 for (j = 0; tests[i].expected[j]; j++)
902 {
905 ok(cf == tests[i].expected[j], "got %04x instead of %04x\n",
906 cf, tests[i].expected[j] );
907 if (cf != tests[i].expected[j])
908 {
910 break;
911 }
912 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
913 ok( !rendered, "formats %08x have been rendered\n", rendered );
915 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
916 if (cf == CF_LOCALE)
917 {
918 ok(data != NULL, "CF_LOCALE no data\n");
919 ok( !rendered, "formats %08x have been rendered\n", rendered );
920 }
921 else
922 {
923 ok(!data, "format %04x got data %p\n", cf, data);
924 ok( rendered == (1 << tests[i].format),
925 "formats %08x have been rendered\n", rendered );
926 /* try to render a second time */
928 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
929 ok( rendered == (1 << tests[i].format),
930 "formats %08x have been rendered\n", rendered );
931 }
933 }
934 if (!tests[i].expected[j])
935 {
937 ok(cf == 0, "cf %04x\n", cf);
938 }
939 r = CloseClipboard();
940 ok(r, "gle %ld\n", GetLastError());
941 rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
942 ok( !rendered, "formats %08x have been rendered\n", rendered );
944 }
945
947 ok(r, "gle %ld\n", GetLastError());
948 r = EmptyClipboard();
949 ok(r, "gle %ld\n", GetLastError());
950 r = CloseClipboard();
951 ok(r, "gle %ld\n", GetLastError());
953
954 /* Check what happens to the delayed rendering clipboard formats when the
955 * owner window is destroyed.
956 */
957 hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
959
961 ok(r, "gle %ld\n", GetLastError());
962 r = EmptyClipboard();
963 ok(r, "gle %ld\n", GetLastError());
965 r = CloseClipboard();
966 ok(r, "gle %ld\n", GetLastError());
967
969 ok(r, "gle %ld\n", GetLastError());
971 ok(count == 4, "count %u\n", count );
972
974
975 /* CF_UNICODETEXT and derivatives, CF_TEXT + CF_OEMTEXT, should be gone */
977 ok(count == 1, "count %u\n", count );
979 ok(cf == CF_LOCALE, "unexpected clipboard format %u\n", cf);
980
981 r = CloseClipboard();
982 ok(r, "gle %ld\n", GetLastError());
983
985 ok(r, "gle %ld\n", GetLastError());
986
987 SetLastError(0xdeadbeef);
989 ok(GetLastError() == ERROR_NOT_FOUND /* win11 */ ||
990 broken(GetLastError() == 0xdeadbeef),
991 "bad last error %ld\n", GetLastError());
992 ok(!data, "GetClipboardData() should have returned NULL\n");
993
994 r = CloseClipboard();
995 ok(r, "gle %ld\n", GetLastError());
996}
997
999{
1001 ok( handle != 0, "SetClipboardData failed: %ld\n", GetLastError() );
1002 return 0;
1003}
1004
1015
1017{
1018 LRESULT ret;
1019 DWORD msg_flags = InSendMessageEx( NULL );
1020
1021 switch(msg) {
1022 case WM_DRAWCLIPBOARD:
1023 ok( msg_flags == (cross_thread ? ISMEX_NOTIFY : ISMEX_NOSEND),
1024 "WM_DRAWCLIPBOARD wrong flags %lx\n", msg_flags );
1028 break;
1029 case WM_CHANGECBCHAIN:
1030 ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND),
1031 "WM_CHANGECBCHAIN wrong flags %lx\n", msg_flags );
1032 if (next_wnd == (HWND)wp)
1033 next_wnd = (HWND)lp;
1034 else if (next_wnd)
1035 SendMessageA(next_wnd, msg, wp, lp);
1036 break;
1038 ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND),
1039 "WM_DESTROYCLIPBOARD wrong flags %lx\n", msg_flags );
1041 ok( GetClipboardOwner() == hwnd, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
1043 break;
1044 case WM_RENDERFORMAT:
1045 ok( !wm_renderformat, "multiple WM_RENDERFORMAT %04x / %04Ix\n", wm_renderformat, wp );
1046 wm_renderformat = wp;
1047
1048 if (do_render_format)
1049 {
1050 UINT seq, old_seq;
1051 HANDLE handle;
1052
1055 ok( handle != 0, "SetClipboardData failed: %ld\n", GetLastError() );
1057 ok( seq == old_seq, "sequence changed\n" );
1058 old_seq = seq;
1059
1061 ok( handle != NULL, "CreateThread failed: %ld\n", GetLastError() );
1062 ok( WaitForSingleObject(handle, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n" );
1065 ok( seq == old_seq, "sequence changed\n" );
1066 }
1067
1068 break;
1069 case WM_CLIPBOARDUPDATE:
1070 ok( msg_flags == ISMEX_NOSEND, "WM_CLIPBOARDUPDATE wrong flags %lx\n", msg_flags );
1075 break;
1076 case WM_USER:
1078 PostQuitMessage(0);
1079 break;
1080 case WM_USER+1:
1082 wm_drawclipboard = 0;
1083 return ret;
1084 case WM_USER+2:
1087 return ret;
1088 case WM_USER+3:
1091 return ret;
1092 case WM_USER+4:
1094 wm_renderformat = 0;
1095 return ret;
1096 case WM_USER+5:
1097 return nb_formats;
1098 }
1099
1100 return DefWindowProcA(hwnd, msg, wp, lp);
1101}
1102
1104{
1105 HANDLE data;
1106 BOOL r;
1107
1108 r = open_clipboard(0);
1109 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1111 ok( data != NULL, "GetClipboardData failed: %ld\n", GetLastError());
1112 r = CloseClipboard();
1113 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1114}
1115
1117
1118static void check_messages_(int line, HWND win, UINT seq_diff, UINT draw, UINT update, UINT destroy, UINT render)
1119{
1120 MSG msg;
1121 UINT count, fmt, seq;
1122
1124 ok_(__FILE__, line)(seq - old_seq == seq_diff, "sequence diff %d\n", seq - old_seq);
1125 old_seq = seq;
1126
1127 if (!cross_thread)
1128 {
1129 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
1130 }
1131
1132 if (update && !broken(!pAddClipboardFormatListener))
1133 ok(WaitForSingleObject(update_event, 1000) == WAIT_OBJECT_0, "wait failed\n");
1134
1135 count = SendMessageA( win, WM_USER + 1, 0, 0 );
1136 ok_(__FILE__, line)(count == draw, "WM_DRAWCLIPBOARD %sreceived\n", draw ? "not " : "");
1137 count = SendMessageA( win, WM_USER + 2, 0, 0 );
1138 ok_(__FILE__, line)(count == update || broken(!pAddClipboardFormatListener),
1139 "WM_CLIPBOARDUPDATE %sreceived\n", update ? "not " : "");
1140 count = SendMessageA( win, WM_USER + 3, 0, 0 );
1141 ok_(__FILE__, line)(count == destroy, "WM_DESTROYCLIPBOARD %sreceived\n", destroy ? "not " : "");
1142 fmt = SendMessageA( win, WM_USER + 4, 0, 0 );
1143 ok_(__FILE__, line)(fmt == render, "WM_RENDERFORMAT received %04x, expected %04x\n", fmt, render);
1144}
1145#define check_messages(a,b,c,d,e,f) check_messages_(__LINE__,a,b,c,d,e,f)
1146
1148{
1149 HWND ret, win = param;
1150 BOOL r;
1151 MSG msg;
1152 HANDLE handle;
1154
1156 trace( "%s-threaded test\n", cross_thread ? "multi" : "single" );
1157
1159
1161 SetLastError(0xdeadbeef);
1163 ok(GetLastError() == 0xdeadbeef, "GetLastError = %ld\n", GetLastError());
1165
1166 SetLastError( 0xdeadbeef );
1167 ret = SetClipboardViewer( (HWND)0xdead );
1168 ok( !ret, "SetClipboardViewer succeeded\n" );
1169 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
1170 SetLastError( 0xdeadbeef );
1171 r = ChangeClipboardChain( win, (HWND)0xdead );
1172 ok( !r, "ChangeClipboardChain succeeded\n" );
1173 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
1174 SetLastError( 0xdeadbeef );
1175 r = ChangeClipboardChain( (HWND)0xdead, next_wnd );
1176 ok( !r, "ChangeClipboardChain succeeded\n" );
1177 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
1178
1179 if (pAddClipboardFormatListener)
1180 {
1181 r = pAddClipboardFormatListener(win);
1182 ok( r, "AddClipboardFormatListener failed err %ld\n", GetLastError());
1183 SetLastError( 0xdeadbeef );
1184 r = pAddClipboardFormatListener( win );
1185 ok( !r, "AddClipboardFormatListener succeeded\n" );
1186 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
1187 SetLastError( 0xdeadbeef );
1188 r = pAddClipboardFormatListener( (HWND)0xdead );
1189 ok( !r, "AddClipboardFormatListener succeeded\n" );
1190 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
1191 r = pAddClipboardFormatListener( GetDesktopWindow() );
1192 ok( r, "AddClipboardFormatListener failed err %ld\n", GetLastError());
1193 r = pRemoveClipboardFormatListener( GetDesktopWindow() );
1194 ok( r, "RemoveClipboardFormatListener failed err %ld\n", GetLastError());
1195 }
1196
1197 check_messages(win, 0, 1, 0, 0, 0);
1198
1199 SetLastError( 0xdeadbeef );
1200 r = OpenClipboard( (HWND)0xdead );
1201 ok( !r, "OpenClipboard succeeded\n" );
1202 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
1203
1204 r = open_clipboard(win);
1205 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1206
1207 check_messages(win, 0, 0, 0, 0, 0);
1208
1209 r = EmptyClipboard();
1210 ok(r, "EmptyClipboard failed: %ld\n", GetLastError());
1211
1212 check_messages(win, 1, 0, 0, 0, 0);
1213
1214 r = EmptyClipboard();
1215 ok(r, "EmptyClipboard failed: %ld\n", GetLastError());
1216 /* sequence changes again, even though it was already empty */
1217 check_messages(win, 1, 0, 0, 1, 0);
1218 count = SendMessageA( win, WM_USER+5, 0, 0 );
1219 ok( !count, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count );
1220
1222 ok(handle != 0, "SetClipboardData failed: %ld\n", GetLastError());
1223
1224 check_messages(win, 1, 0, 0, 0, 0);
1225
1227
1228 check_messages(win, 1, 0, 0, 0, 0);
1229
1230 SetClipboardData( CF_UNICODETEXT, 0 ); /* same data again */
1231
1232 check_messages(win, 1, 0, 0, 0, 0);
1233
1234 ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" );
1235 ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" );
1236 ok( !IsClipboardFormatAvailable( CF_OEMTEXT ), "CF_OEMTEXT available\n" );
1237
1239 r = CloseClipboard();
1240 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1242
1243 check_messages(win, 2, 1, 1, 0, 0);
1244
1245 r = open_clipboard(win);
1246 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1247
1248 check_messages(win, 0, 0, 0, 0, 0);
1249
1250 ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" );
1251 ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" );
1252 ok( IsClipboardFormatAvailable( CF_OEMTEXT ), "CF_OEMTEXT available\n" );
1253
1254 ok( GetClipboardOwner() == win, "wrong owner %p\n", GetClipboardOwner());
1256 ok( !handle, "got data for CF_UNICODETEXT\n" );
1257 fmt = SendMessageA( win, WM_USER+4, 0, 0 );
1258 ok( fmt == CF_UNICODETEXT, "WM_RENDERFORMAT received %04x\n", fmt );
1259
1262 ok( handle != NULL, "didn't get data for CF_OEMTEXT\n" );
1263 fmt = SendMessageA( win, WM_USER+4, 0, 0 );
1264 ok( fmt == CF_UNICODETEXT, "WM_RENDERFORMAT received %04x\n", fmt );
1266
1268 check_messages(win, 1, 0, 0, 0, 0);
1269
1270 r = CloseClipboard();
1271 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1272 /* no synthesized format, so CloseClipboard doesn't change the sequence */
1273 check_messages(win, 0, 1, 1, 0, 0);
1274
1275 r = open_clipboard(win);
1276 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1277 r = CloseClipboard();
1278 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1279 /* nothing changed */
1280 check_messages(win, 0, 0, 0, 0, 0);
1281
1283 r = open_clipboard(0);
1284 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1285 r = EmptyClipboard();
1286 ok(r, "EmptyClipboard failed: %ld\n", GetLastError());
1287 r = CloseClipboard();
1288 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1289
1290 check_messages(win, 1, 1, 1, 1, 0);
1291 count = SendMessageA( win, WM_USER+5, 0, 0 );
1292 ok( count == formats, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count );
1293
1294 r = open_clipboard(win);
1295 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1297 check_messages(win, 1, 0, 0, 0, 0);
1298
1300 r = CloseClipboard();
1301 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1303
1304 check_messages(win, 0, 1, 1, 0, 0);
1305
1306 run_process( "grab_clipboard 0" );
1307
1308 if (!cross_thread)
1309 {
1310 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1312 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
1314 }
1315 check_messages(win, 1, 1, 1, 0, 0);
1316
1317 r = open_clipboard(0);
1318 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1320 check_messages(win, 1, 0, 0, 0, 0);
1321
1323 r = CloseClipboard();
1324 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1326
1327 check_messages(win, 0, 1, 1, 0, 0);
1328
1329 run_process( "grab_clipboard 1" );
1330
1331 if (!cross_thread)
1332 {
1333 /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1335 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
1337 }
1338 check_messages(win, 2, 1, 1, 0, 0);
1339
1340 r = open_clipboard(0);
1341 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1343 check_messages(win, 1, 0, 0, 0, 0);
1344
1346 r = CloseClipboard();
1347 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1349
1350 check_messages(win, 0, 1, 1, 0, 0);
1351
1352 if (cross_thread)
1353 {
1354 r = open_clipboard( win );
1355 ok(r, "OpenClipboard failed: %ld\n", GetLastError());
1356 r = EmptyClipboard();
1357 ok(r, "EmptyClipboard failed: %ld\n", GetLastError());
1359 r = CloseClipboard();
1360 ok(r, "CloseClipboard failed: %ld\n", GetLastError());
1361
1364 run_process( "get_clipboard_data" );
1366
1367 check_messages(win, 0, 1, 1, 0, CF_TEXT);
1368 }
1369
1370 r = PostMessageA(win, WM_USER, 0, 0);
1371 ok(r, "PostMessage failed: %ld\n", GetLastError());
1372
1373 if (pRemoveClipboardFormatListener)
1374 {
1375 r = pRemoveClipboardFormatListener(win);
1376 ok( r, "RemoveClipboardFormatListener failed err %ld\n", GetLastError());
1377 SetLastError( 0xdeadbeef );
1378 r = pRemoveClipboardFormatListener(win);
1379 ok( !r, "RemoveClipboardFormatListener succeeded\n" );
1380 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
1381 SetLastError( 0xdeadbeef );
1382 r = pRemoveClipboardFormatListener( (HWND)0xdead );
1383 ok( !r, "RemoveClipboardFormatListener succeeded\n" );
1384 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
1385 }
1386 return 0;
1387}
1388
1389static void test_messages(void)
1390{
1391 WNDCLASSA cls;
1392 HWND win;
1393 MSG msg;
1394 HANDLE thread;
1395 DWORD tid;
1396
1399
1400 memset(&cls, 0, sizeof(cls));
1403 cls.lpszClassName = "clipboard_test";
1404 RegisterClassA(&cls);
1405
1406 win = CreateWindowA("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0);
1407 ok(win != NULL, "CreateWindow failed: %ld\n", GetLastError());
1408
1409 thread = CreateThread(NULL, 0, clipboard_thread, (void*)win, 0, &tid);
1410 ok(thread != NULL, "CreateThread failed: %ld\n", GetLastError());
1411
1412 while(GetMessageA(&msg, NULL, 0, 0))
1413 {
1414 ok( msg.message != WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD was posted\n" );
1417 }
1418
1419 ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1421
1422 DestroyWindow( win );
1423
1424 /* same tests again but inside a single thread */
1425
1426 win = CreateWindowA( "clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0 );
1427 ok( win != NULL, "CreateWindow failed: %ld\n", GetLastError() );
1428
1430 DestroyWindow( win );
1431
1432 UnregisterClassA("clipboard_test", GetModuleHandleA(NULL));
1434}
1435
1437{
1438 void *ptr = GlobalLock( handle );
1439 if (ptr) GlobalUnlock( handle );
1440 return ptr && ptr != handle;
1441}
1442
1444{
1445 void *ptr = GlobalLock( handle );
1446 if (ptr) GlobalUnlock( handle );
1447 return ptr && ptr == handle;
1448}
1449
1451{
1452 return !GlobalSize( handle );
1453}
1454
1457static HPALETTE palette;
1458static const LOGPALETTE logpalette = { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}};
1459
1460static void test_handles( HWND hwnd )
1461{
1462 HGLOBAL h, htext, htext2, htext3, htext4, htext5;
1463 HGLOBAL hfixed, hfixed2, hmoveable, empty_fixed, empty_moveable;
1464 void *ptr;
1465 UINT format_id2 = RegisterClipboardFormatA( "another format" );
1466 BOOL r;
1467 HANDLE data;
1468 HBITMAP bitmap_temp;
1469 DWORD process;
1471
1472 trace( "hwnd %p\n", hwnd );
1473 htext = create_textA();
1474 htext2 = create_textA();
1475 htext3 = create_textA();
1476 htext4 = create_textA();
1477 htext5 = create_textA();
1478 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
1479 bitmap2 = CreateBitmap( 10, 10, 1, 1, NULL );
1481
1482 hfixed = GlobalAlloc( GMEM_FIXED, 17 );
1483 hfixed2 = GlobalAlloc( GMEM_FIXED, 17 );
1484 ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1485 ok( GlobalSize( hfixed ) == 17, "wrong size %Iu\n", GlobalSize( hfixed ));
1486
1487 hmoveable = GlobalAlloc( GMEM_MOVEABLE, 23 );
1488 ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable );
1489 ok( GlobalSize( hmoveable ) == 23, "wrong size %Iu\n", GlobalSize( hmoveable ));
1490
1491 empty_fixed = GlobalAlloc( GMEM_FIXED, 0 );
1492 ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1493
1494 empty_moveable = GlobalAlloc( GMEM_MOVEABLE, 0 );
1495 /* discarded handles can't be GlobalLock'ed */
1496 ok( is_freed( empty_moveable ), "expected free mem %p\n", empty_moveable );
1497
1498 r = open_clipboard( hwnd );
1499 ok( r, "gle %ld\n", GetLastError() );
1500 r = EmptyClipboard();
1501 ok( r, "gle %ld\n", GetLastError() );
1502
1503 h = SetClipboardData( CF_TEXT, htext );
1504 ok( h == htext, "got %p\n", h );
1505 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1506 h = SetClipboardData( format_id, htext2 );
1507 ok( h == htext2, "got %p\n", h );
1508 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1509 bitmap_temp = CreateBitmap( 10, 10, 1, 1, NULL );
1510 h = SetClipboardData( CF_BITMAP, bitmap_temp );
1511 ok( h == bitmap_temp, "got %p\n", h );
1512 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1514 ok( h == bitmap, "got %p\n", h );
1515 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1517 ok( h == bitmap2, "got %p\n", h );
1518 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1520 ok( h == palette, "got %p\n", h );
1521 ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1522 h = SetClipboardData( CF_GDIOBJFIRST + 3, htext3 );
1523 ok( h == htext3, "got %p\n", h );
1524 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1525 h = SetClipboardData( CF_PRIVATEFIRST + 7, htext5 );
1526 ok( h == htext5, "got %p\n", h );
1527 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1528 h = SetClipboardData( format_id2, empty_moveable );
1529 ok( !h, "got %p\n", h );
1530 GlobalFree( empty_moveable );
1531
1532 if (0) /* crashes on vista64 */
1533 {
1534 ptr = HeapAlloc( GetProcessHeap(), 0, 0 );
1535 h = SetClipboardData( format_id2, ptr );
1536 ok( !h, "got %p\n", h );
1537 HeapFree( GetProcessHeap(), 0, ptr );
1538 }
1539
1540 h = SetClipboardData( format_id2, empty_fixed );
1541 ok( h == empty_fixed, "got %p\n", h );
1542 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1543 h = SetClipboardData( 0xdeadbeef, hfixed2 );
1544 ok( h == hfixed2, "got %p\n", h );
1545 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1546 h = SetClipboardData( 0xdeadbabe, hmoveable );
1547 ok( h == hmoveable, "got %p\n", h );
1548 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1549
1550 ptr = HeapAlloc( GetProcessHeap(), 0, 37 );
1551 h = SetClipboardData( 0xdeadfade, ptr );
1552 ok( h == ptr || !h, "got %p\n", h );
1553 if (!h) /* heap blocks are rejected on >= win8 */
1554 {
1555 HeapFree( GetProcessHeap(), 0, ptr );
1556 ptr = NULL;
1557 }
1558
1560 ok( data == htext, "wrong data %p\n", data );
1561 ok( is_moveable( data ), "expected moveable mem %p\n", data );
1562
1564 ok( data == htext2, "wrong data %p, cf %08x\n", data, format_id );
1565 ok( is_moveable( data ), "expected moveable mem %p\n", data );
1566
1568 ok( data == htext3, "wrong data %p\n", data );
1569 ok( is_moveable( data ), "expected moveable mem %p\n", data );
1570
1572 ok( data == htext5, "wrong data %p\n", data );
1573 ok( is_moveable( data ), "expected moveable mem %p\n", data );
1574
1575 data = GetClipboardData( format_id2 );
1576 ok( data == empty_fixed, "wrong data %p\n", data );
1577 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1578
1579 data = GetClipboardData( 0xdeadbeef );
1580 ok( data == hfixed2, "wrong data %p\n", data );
1581 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1582
1583 data = GetClipboardData( 0xdeadbabe );
1584 ok( data == hmoveable, "wrong data %p\n", data );
1585 ok( is_moveable( data ), "expected moveable mem %p\n", data );
1586
1587 data = GetClipboardData( 0xdeadfade );
1588 ok( data == ptr, "wrong data %p\n", data );
1589
1590 SetLastError( 0xdeadbeef );
1592 ok( GetLastError() == ERROR_NOT_FOUND /* win11 */ ||
1593 broken(GetLastError() == 0xdeadbeef),
1594 "unexpected last error %ld\n", GetLastError() );
1595 ok( !data, "wrong data %p\n", data );
1596
1597 h = SetClipboardData( CF_PRIVATEFIRST + 7, htext4 );
1598 ok( h == htext4, "got %p\n", h );
1599 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1600 ok( is_freed( htext5 ), "expected freed mem %p\n", htext5 );
1601
1602 h = SetClipboardData( 0xdeadbeef, hfixed );
1603 ok( h == hfixed, "got %p\n", h );
1604 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1605 if (0) /* this test is unreliable / crashes */
1606 ok( is_freed( hfixed2 ), "expected freed mem %p\n", hfixed2 );
1607
1608 r = CloseClipboard();
1609 ok( r, "gle %ld\n", GetLastError() );
1610
1611 /* data handles are still valid */
1612 ok( is_moveable( htext ), "expected moveable mem %p\n", htext );
1613 ok( is_moveable( htext2 ), "expected moveable mem %p\n", htext2 );
1614 ok( is_moveable( htext3 ), "expected moveable mem %p\n", htext3 );
1615 ok( is_moveable( htext4 ), "expected moveable mem %p\n", htext4 );
1616 ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap );
1617 ok( GetObjectType( bitmap2 ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap2 );
1618 ok( GetObjectType( palette ) == OBJ_PAL, "expected palette %p\n", palette );
1619 ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1620 ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable );
1621 ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1622
1623 r = open_clipboard( hwnd );
1624 ok( r, "gle %ld\n", GetLastError() );
1625
1626 /* and now they are freed, unless we are the owner */
1627 if (!is_owner)
1628 {
1629 ok( is_freed( htext ), "expected freed mem %p\n", htext );
1630 ok( is_freed( htext2 ), "expected freed mem %p\n", htext2 );
1631 ok( is_freed( htext3 ), "expected freed mem %p\n", htext3 );
1632 ok( is_freed( htext4 ), "expected freed mem %p\n", htext4 );
1633 ok( is_freed( hmoveable ), "expected freed mem %p\n", hmoveable );
1634
1636 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1637
1639 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1640
1642 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1643
1645 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1646
1647 data = GetClipboardData( format_id2 );
1648 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1649 ok( GlobalSize( data ) == 1, "wrong size %Iu\n", GlobalSize( data ));
1650
1651 data = GetClipboardData( 0xdeadbeef );
1652 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1653 ok( GlobalSize( data ) == 17, "wrong size %Iu\n", GlobalSize( data ));
1654
1655 data = GetClipboardData( 0xdeadbabe );
1656 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1657 ok( GlobalSize( data ) == 23, "wrong size %Iu\n", GlobalSize( data ));
1658
1659 data = GetClipboardData( 0xdeadfade );
1660 ok( is_fixed( data ) || !ptr, "expected fixed mem %p\n", data );
1661 if (ptr) ok( GlobalSize( data ) == 37, "wrong size %Iu\n", GlobalSize( data ));
1662 }
1663 else
1664 {
1665 ok( is_moveable( htext ), "expected moveable mem %p\n", htext );
1666 ok( is_moveable( htext2 ), "expected moveable mem %p\n", htext2 );
1667 ok( is_moveable( htext3 ), "expected moveable mem %p\n", htext3 );
1668 ok( is_moveable( htext4 ), "expected moveable mem %p\n", htext4 );
1669 ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable );
1670
1672 ok( data == htext, "wrong data %p\n", data );
1673
1675 ok( data == htext2, "wrong data %p, cf %08x\n", data, format_id );
1676
1678 ok( data == htext3, "wrong data %p\n", data );
1679
1681 ok( data == htext4, "wrong data %p\n", data );
1682
1683 data = GetClipboardData( format_id2 );
1684 ok( data == empty_fixed, "wrong data %p\n", data );
1685
1686 data = GetClipboardData( 0xdeadbeef );
1687 ok( data == hfixed, "wrong data %p\n", data );
1688
1689 data = GetClipboardData( 0xdeadbabe );
1690 ok( data == hmoveable, "wrong data %p\n", data );
1691
1692 data = GetClipboardData( 0xdeadfade );
1693 ok( data == ptr, "wrong data %p\n", data );
1694 }
1695
1697 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1699 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1701 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1703 ok( data == bitmap, "expected bitmap %p\n", data );
1705 ok( data == bitmap2, "expected bitmap %p\n", data );
1707 ok( data == palette, "expected palette %p\n", data );
1709 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1710 data = GetClipboardData( CF_DIBV5 );
1711 ok( is_fixed( data ), "expected fixed mem %p\n", data );
1712
1713 ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap );
1714 ok( GetObjectType( bitmap2 ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap2 );
1715 ok( GetObjectType( palette ) == OBJ_PAL, "expected palette %p\n", palette );
1716 ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1717 ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1718
1719 r = EmptyClipboard();
1720 ok( r, "gle %ld\n", GetLastError() );
1721
1722 /* w2003, w2008 don't seem to free the data here */
1723 ok( is_freed( htext ) || broken( !is_freed( htext )), "expected freed mem %p\n", htext );
1724 ok( is_freed( htext2 ) || broken( !is_freed( htext2 )), "expected freed mem %p\n", htext2 );
1725 ok( is_freed( htext3 ) || broken( !is_freed( htext3 )), "expected freed mem %p\n", htext3 );
1726 ok( is_freed( htext4 ) || broken( !is_freed( htext4 )), "expected freed mem %p\n", htext4 );
1727 ok( is_freed( hmoveable ) || broken( !is_freed( hmoveable )), "expected freed mem %p\n", hmoveable );
1728 ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1729 ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1730
1731 r = CloseClipboard();
1732 ok( r, "gle %ld\n", GetLastError() );
1733}
1734
1736{
1737 trace( "running from different thread\n" );
1738 test_handles( (HWND)arg );
1739 return 0;
1740}
1741
1743{
1744 BOOL r;
1745 HANDLE h;
1746 char *ptr;
1747
1748 r = open_clipboard( 0 );
1749 ok( r, "gle %ld\n", GetLastError() );
1751 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1752 ptr = GlobalLock( h );
1753 if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1754 GlobalUnlock( h );
1756 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1757 ptr = GlobalLock( h );
1758 if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1759 GlobalUnlock( h );
1761 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1762 ptr = GlobalLock( h );
1763 if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1764 GlobalUnlock( h );
1765 trace( "gdiobj %p\n", h );
1767 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1768 ptr = GlobalLock( h );
1769 if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1770 GlobalUnlock( h );
1771 trace( "private %p\n", h );
1773 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1774 ok( h == bitmap, "different bitmap %p / %p\n", h, bitmap );
1775 trace( "bitmap %p\n", h );
1777 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1778 ok( h == bitmap2, "different bitmap %p / %p\n", h, bitmap2 );
1779 trace( "bitmap2 %p\n", h );
1781 ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1782 ok( h == palette, "different palette %p / %p\n", h, palette );
1783 trace( "palette %p\n", h );
1785 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1786 h = GetClipboardData( CF_DIBV5 );
1787 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1788 r = CloseClipboard();
1789 ok( r, "gle %ld\n", GetLastError() );
1790 return 0;
1791}
1792
1793static void test_handles_process( const char *str )
1794{
1795 BOOL r;
1796 HANDLE h;
1797 char *ptr;
1798 BITMAP bm;
1800 BYTE buffer[1024];
1801
1802 format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" );
1803 r = open_clipboard( 0 );
1804 ok( r, "gle %ld\n", GetLastError() );
1806 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1807 ptr = GlobalLock( h );
1808 ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1809 GlobalUnlock( h );
1811 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1812 ptr = GlobalLock( h );
1813 if (ptr) ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1814 GlobalUnlock( h );
1816 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1817 ptr = GlobalLock( h );
1818 ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1819 GlobalUnlock( h );
1820 trace( "gdiobj %p\n", h );
1822 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1823 ptr = GlobalLock( h );
1824 ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1825 GlobalUnlock( h );
1826 trace( "private %p\n", h );
1828 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1829 ok( GetObjectW( h, sizeof(bm), &bm ) == sizeof(bm), "GetObject %p failed\n", h );
1830 ok( bm.bmWidth == 13 && bm.bmHeight == 17, "wrong bitmap %ux%u\n", bm.bmWidth, bm.bmHeight );
1831 trace( "bitmap %p\n", h );
1833 ok( !GetObjectType( h ), "expected invalid object %p\n", h );
1834 trace( "bitmap2 %p\n", h );
1836 ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1837 ok( GetPaletteEntries( h, 0, 1, &entry ) == 1, "GetPaletteEntries %p failed\n", h );
1838 ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56,
1839 "wrong color %02x,%02x,%02x\n", entry.peRed, entry.peGreen, entry.peBlue );
1840 trace( "palette %p\n", h );
1842 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1843 ok( GetObjectType( ((METAFILEPICT *)h)->hMF ) == OBJ_METAFILE,
1844 "wrong object %p\n", ((METAFILEPICT *)h)->hMF );
1845 trace( "metafile %p\n", h );
1847 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1848 ok( GetObjectType( ((METAFILEPICT *)h)->hMF ) == OBJ_METAFILE,
1849 "wrong object %p\n", ((METAFILEPICT *)h)->hMF );
1850 trace( "metafile2 %p\n", h );
1852 ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1853 ok( GetEnhMetaFileBits( h, sizeof(buffer), buffer ) > sizeof(ENHMETAHEADER),
1854 "GetEnhMetaFileBits failed on %p\n", h );
1855 ok( ((ENHMETAHEADER *)buffer)->nRecords == 3,
1856 "wrong records %lu\n", ((ENHMETAHEADER *)buffer)->nRecords );
1857 trace( "enhmetafile %p\n", h );
1859 ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1860 ok( GetEnhMetaFileBits( h, sizeof(buffer), buffer ) > sizeof(ENHMETAHEADER),
1861 "GetEnhMetaFileBits failed on %p\n", h );
1862 ok( ((ENHMETAHEADER *)buffer)->nRecords == 3,
1863 "wrong records %lu\n", ((ENHMETAHEADER *)buffer)->nRecords );
1864 trace( "enhmetafile2 %p\n", h );
1866 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1867 h = GetClipboardData( CF_DIBV5 );
1868 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1869 r = CloseClipboard();
1870 ok( r, "gle %ld\n", GetLastError() );
1871}
1872
1873static void test_handles_process_open( const char *str )
1874{
1876 char *ptr = GlobalLock( text );
1877
1878 strcpy( ptr, str );
1879 GlobalUnlock( text );
1880
1881 /* clipboard already open by parent process */
1883 ok( h == text, "wrong mem %p / %p\n", h, text );
1884 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1885}
1886
1887static void test_handles_process_dib( const char *str )
1888{
1889 BOOL r;
1890 HANDLE h;
1891
1892 r = open_clipboard( 0 );
1893 ok( r, "gle %ld\n", GetLastError() );
1895 ok( !GetObjectType( h ), "expected invalid object %p\n", h );
1896 trace( "dibsection %p\n", h );
1897 r = CloseClipboard();
1898 ok( r, "gle %ld\n", GetLastError() );
1899}
1900
1901static void test_data_handles(void)
1902{
1903 BOOL r;
1904 char *ptr;
1906 HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
1907 BITMAPINFO bmi;
1908 void *bits;
1910 BYTE buffer[1024];
1911 HENHMETAFILE emf;
1912 int result;
1913 HDC hdc = GetDC( 0 );
1914
1915 ok( hwnd != 0, "window creation failed\n" );
1916 format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" );
1917 test_handles( 0 );
1919 test_handles( hwnd );
1920 run_thread( test_handles_thread, hwnd, __LINE__ );
1921
1922 bitmap = CreateBitmap( 13, 17, 1, 1, NULL );
1923 bitmap2 = CreateBitmap( 10, 10, 1, 1, NULL );
1925
1926 r = open_clipboard( hwnd );
1927 ok( r, "gle %ld\n", GetLastError() );
1928 r = EmptyClipboard();
1929 ok( r, "gle %ld\n", GetLastError() );
1931 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1933 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1935 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1937 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1939 ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1941 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1942 trace( "metafile %p\n", h );
1944 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1945 trace( "metafile2 %p\n", h );
1947 ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1948 trace( "enhmetafile %p\n", h );
1950 ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1951 trace( "enhmetafile2 %p\n", h );
1953 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1955 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1956 r = CloseClipboard();
1957 ok( r, "gle %ld\n", GetLastError() );
1958
1959 run_thread( test_handles_thread2, 0, __LINE__ );
1960 run_process( "handles test" );
1961
1962 r = open_clipboard( hwnd );
1963 ok( r, "gle %ld\n", GetLastError() );
1965 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1967 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1969 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1971 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1972
1973 r = EmptyClipboard();
1974 ok( r, "gle %ld\n", GetLastError() );
1975 text = create_textA();
1977 ok( is_moveable( h ), "expected moveable mem %p\n", h );
1978
1979 run_process( "handles_open foobar" );
1980
1981 ok( is_moveable( text ), "expected moveable mem %p\n", text );
1983 ok( is_fixed( h ), "expected fixed mem %p\n", h );
1984 ok( is_moveable( text ), "expected moveable mem %p\n", text );
1985 ptr = GlobalLock( h );
1986 ok( ptr && !strcmp( ptr, "foobar" ), "wrong data %s\n", wine_dbgstr_a(ptr) );
1987 GlobalUnlock( h );
1988
1989 r = EmptyClipboard();
1990 ok( r, "gle %ld\n", GetLastError() );
1991 ok( is_fixed( h ), "expected free mem %p\n", h );
1992 ok( is_freed( text ) || broken( is_moveable(text) ), /* w2003, w2008 */
1993 "expected free mem %p\n", text );
1994 r = CloseClipboard();
1995 ok( r, "gle %ld\n", GetLastError() );
1996
1997 /* test CF_BITMAP with a DIB section */
1998 memset( &bmi, 0, sizeof(bmi) );
1999 bmi.bmiHeader.biSize = sizeof( bmi.bmiHeader );
2000 bmi.bmiHeader.biWidth = 29;
2001 bmi.bmiHeader.biHeight = 13;
2002 bmi.bmiHeader.biPlanes = 1;
2003 bmi.bmiHeader.biBitCount = 32;
2004 bitmap = CreateDIBSection( 0, &bmi, DIB_RGB_COLORS, &bits, 0, 0 );
2005
2006 r = open_clipboard( hwnd );
2007 ok( r, "gle %ld\n", GetLastError() );
2008 r = EmptyClipboard();
2009 ok( r, "gle %ld\n", GetLastError() );
2011 ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
2012 trace( "dibsection %p\n", h );
2013 r = CloseClipboard();
2014 ok( r, "gle %ld\n", GetLastError() );
2015
2016 run_process( "handles_dib dummy" );
2017
2018 r = open_clipboard( hwnd );
2019 ok( r, "gle %ld\n", GetLastError() );
2020 ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap );
2021 r = EmptyClipboard();
2022 ok( r, "gle %ld\n", GetLastError() );
2023 r = CloseClipboard();
2024 ok( r, "gle %ld\n", GetLastError() );
2025
2026 r = open_clipboard( hwnd );
2027 ok( r, "Open clipboard failed: %#lx.\n", GetLastError() );
2028 r = EmptyClipboard();
2029 ok( r, "EmptyClipboard failed: %#lx.\n", GetLastError() );
2030
2031 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
2033 ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
2034 ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" );
2036 ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
2037 memset( &bmi, 0, sizeof(bmi) );
2038 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2039 result = GetDIBits( hdc, h, 0, 0, NULL, &bmi, 0 );
2040 ok( !!result, "GetDIBits failed: %#lx.\n", GetLastError() );
2041
2042 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
2044 ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
2045 ok( !!DeleteObject( bitmap ), "DeleteObject failed.\n" );
2047 ok( h == bitmap, "Expected bitmap %p, got %p.\n", bitmap, h );
2048 memset( &bmi, 0, sizeof(bmi) );
2049 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2050 ok( !GetDIBits( hdc, h, 0, 0, 0, &bmi, 0 ), "GetDIBits returned unexpected value.\n" );
2051
2054 ok( h == palette, "Expected palette %p, got %p.\n", palette, h );
2055 ok( !!DeleteObject( palette ), "DeleteObject failed.\n" );
2057 ok( h == palette, "Expected palette %p, got %p.\n", palette, h );
2058 ok( !!GetPaletteEntries( h, 0, 1, &entry ), "GetPaletteEntries %p failed.\n", h );
2059 ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56,
2060 "Got wrong color (%02x, %02x, %02x).\n", entry.peRed, entry.peGreen, entry.peBlue );
2061
2062 emf = create_emf();
2064 ok( h == emf, "Expected enhmetafile %p, got %p.\n", palette, h );
2065 ok( !!DeleteEnhMetaFile( emf ), "DeleteEnhMetaFile failed.\n" );
2067 ok( h == emf, "Expected enhmetafile %p, got %p.\n", palette, h );
2068 ok( !GetEnhMetaFileBits( h, sizeof(buffer), buffer ), "GetEnhMetaFileBits returned unexpected value.\n" );
2069
2070 emf = create_emf();
2072 ok( h == emf, "Expected enhmetafile %p, got %p.\n", emf, h );
2073 ok( !!DeleteEnhMetaFile( emf ), "DeleteEnhMetaFile failed.\n" );
2075 ok( h == emf, "Expected enhmetafile %p, got %p.\n", emf, h );
2076 ok( !GetEnhMetaFileBits( h, sizeof(buffer), buffer ), "GetEnhMetaFileBits returned unexpected value.\n" );
2077
2080 ok( h == metafile, "Expected metafilepict %p, got %p.\n", metafile, h );
2081 ok( !pGlobalFree( metafile ), "GlobalFree failed.\n" );
2083 ok( h == metafile, "Expected metafile %p, got %p.\n", metafile, h );
2084 ok( is_freed( h ), "Expected freed mem %p.\n", h );
2085
2088 ok( h == metafile, "Expected metafilepict %p, got %p.\n", metafile, h );
2089 ok( !pGlobalFree( metafile ), "GlobalFree failed.\n" );
2091 ok( h == metafile, "Expected metafile %p, got %p.\n", metafile, h );
2092 ok( is_freed( h ), "Expected freed mem %p.\n", h );
2093
2094 r = EmptyClipboard();
2095 ok( r, "EmptyClipboard failed: %#lx.\n", GetLastError() );
2096 r = CloseClipboard();
2097 ok( r, "CloseClipboard failed: %#lx.\n", GetLastError() );
2098
2099 ReleaseDC( 0, hdc );
2101}
2102
2104{
2105 BOOL r;
2106 UINT count, formats[256];
2107
2108 if (!pGetUpdatedClipboardFormats)
2109 {
2110 win_skip( "GetUpdatedClipboardFormats not supported\n" );
2111 return;
2112 }
2113
2114 count = 0xdeadbeef;
2115 r = pGetUpdatedClipboardFormats( NULL, 0, &count );
2116 ok( r, "gle %ld\n", GetLastError() );
2117 ok( !count, "wrong count %u\n", count );
2118
2119 count = 0xdeadbeef;
2120 r = pGetUpdatedClipboardFormats( NULL, 256, &count );
2121 ok( r, "gle %ld\n", GetLastError() );
2122 ok( !count, "wrong count %u\n", count );
2123
2124 SetLastError( 0xdeadbeef );
2125 r = pGetUpdatedClipboardFormats( formats, ARRAY_SIZE(formats), NULL );
2126 ok( !r, "succeeded\n" );
2127 ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
2128
2129 count = 0xdeadbeef;
2130 r = pGetUpdatedClipboardFormats( formats, ARRAY_SIZE(formats), &count );
2131 ok( r, "gle %ld\n", GetLastError() );
2132 ok( !count, "wrong count %u\n", count );
2133
2134 r = open_clipboard( 0 );
2135 ok( r, "gle %ld\n", GetLastError() );
2136 r = EmptyClipboard();
2137 ok( r, "gle %ld\n", GetLastError() );
2138
2139 count = 0xdeadbeef;
2140 r = pGetUpdatedClipboardFormats( formats, ARRAY_SIZE(formats), &count );
2141 ok( r, "gle %ld\n", GetLastError() );
2142 ok( !count, "wrong count %u\n", count );
2143
2145
2146 count = 0xdeadbeef;
2147 memset( formats, 0xcc, sizeof(formats) );
2148 r = pGetUpdatedClipboardFormats( formats, ARRAY_SIZE(formats), &count );
2149 ok( r, "gle %ld\n", GetLastError() );
2150 ok( count == 1, "wrong count %u\n", count );
2151 ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] );
2152 ok( formats[1] == 0xcccccccc, "wrong format %u\n", formats[1] );
2153
2155 count = 0xdeadbeef;
2156 memset( formats, 0xcc, sizeof(formats) );
2157 r = pGetUpdatedClipboardFormats( formats, ARRAY_SIZE(formats), &count );
2158 ok( r, "gle %ld\n", GetLastError() );
2159 ok( count == 2, "wrong count %u\n", count );
2160 ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] );
2161 ok( formats[1] == CF_TEXT, "wrong format %u\n", formats[1] );
2162 ok( formats[2] == 0xcccccccc, "wrong format %u\n", formats[2] );
2163
2164 SetLastError( 0xdeadbeef );
2165 count = 0xdeadbeef;
2166 r = pGetUpdatedClipboardFormats( formats, 0, &count );
2167 ok( !r, "succeeded\n" );
2168 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %lu\n", GetLastError() );
2169 ok( count == 2, "wrong count %u\n", count );
2170
2171 SetLastError( 0xdeadbeef );
2172 count = 0xdeadbeef;
2173 r = pGetUpdatedClipboardFormats( formats, 1, &count );
2174 ok( !r, "succeeded\n" );
2175 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %lu\n", GetLastError() );
2176 ok( count == 2, "wrong count %u\n", count );
2177
2178 r = CloseClipboard();
2179 ok( r, "gle %ld\n", GetLastError() );
2180
2181 count = 0xdeadbeef;
2182 memset( formats, 0xcc, sizeof(formats) );
2183 r = pGetUpdatedClipboardFormats( formats, ARRAY_SIZE(formats), &count );
2184 ok( r, "gle %ld\n", GetLastError() );
2185 ok( count == 4, "wrong count %u\n", count );
2186 ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] );
2187 ok( formats[1] == CF_TEXT, "wrong format %u\n", formats[1] );
2188 ok( formats[2] == CF_LOCALE, "wrong format %u\n", formats[2] );
2189 ok( formats[3] == CF_OEMTEXT, "wrong format %u\n", formats[3] );
2190 ok( formats[4] == 0xcccccccc, "wrong format %u\n", formats[4] );
2191
2192 count = 0xdeadbeef;
2193 memset( formats, 0xcc, sizeof(formats) );
2194 r = pGetUpdatedClipboardFormats( formats, 2, &count );
2195 ok( !r, "gle %ld\n", GetLastError() );
2196 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %lu\n", GetLastError() );
2197 ok( count == 4, "wrong count %u\n", count );
2198 ok( formats[0] == 0xcccccccc, "wrong format %u\n", formats[0] );
2199
2200 count = 0xdeadbeef;
2201 r = pGetUpdatedClipboardFormats( NULL, 256, &count );
2202 ok( !r, "gle %ld\n", GetLastError() );
2203 ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
2204 ok( count == 4, "wrong count %u\n", count );
2205
2206 count = 0xdeadbeef;
2207 r = pGetUpdatedClipboardFormats( NULL, 256, &count );
2208 ok( !r, "gle %ld\n", GetLastError() );
2209 ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
2210 ok( count == 4, "wrong count %u\n", count );
2211}
2212
2213static const struct
2214{
2215 char strA[12];
2218} test_data[] =
2219{
2220#if defined(__REACTOS__) && defined(_MSC_VER) && _MSVC_VER < 1930
2221 { "foo", {0}, 3 }, /* 0 */
2222 { "foo", {0}, 4 },
2223 { "foo\0bar", {0}, 7 },
2224 { "foo\0bar", {0}, 8 },
2225 { "", {0}, 0 },
2226#else
2227 { "foo", {}, 3 }, /* 0 */
2228 { "foo", {}, 4 },
2229 { "foo\0bar", {}, 7 },
2230 { "foo\0bar", {}, 8 },
2231 { "", {}, 0 },
2232#endif
2233 { "", {'f'}, 1 }, /* 5 */
2234 { "", {'f'}, 2 },
2235 { "", {0x3b1,0x3b2,0x3b3}, 5 }, /* Alpha, beta, ... */
2236 { "", {0x3b1,0x3b2,0x3b3}, 6 },
2237 { "", {0x3b1,0x3b2,0x3b3,0}, 7 }, /* 10 */
2238 { "", {0x3b1,0x3b2,0x3b3,0}, 8 },
2239 { "", {0x3b1,0x3b2,0x3b3,0,0x3b4}, 9 },
2240 { "", {'f','o','o',0,'b','a','r'}, 7 * sizeof(WCHAR) },
2241 { "", {'f','o','o',0,'b','a','r',0}, 8 * sizeof(WCHAR) },
2243
2244static void test_string_data(void)
2245{
2246 UINT i;
2247 BOOL r;
2248 HANDLE data, clip;
2249 char cmd[16];
2250 char bufferA[12];
2251 WCHAR bufferW[12];
2252
2253 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2254 {
2255#ifdef _WIN64
2256 /* Before Windows 11 1-byte Unicode strings crash on Win64
2257 * because it underflows when 'appending' a 2 bytes NUL character!
2258 */
2259 if (!test_data[i].strA[0] && test_data[i].len < sizeof(WCHAR) &&
2260 strcmp(winetest_platform, "windows") == 0) continue;
2261#endif
2262 winetest_push_context("%d", i);
2263 r = open_clipboard( 0 );
2264 ok( r, "gle %ld\n", GetLastError() );
2265 r = EmptyClipboard();
2266 ok( r, "gle %ld\n", GetLastError() );
2268 if (test_data[i].strA[0])
2269 {
2272 memcpy( bufferA, test_data[i].strA, test_data[i].len );
2273 bufferA[test_data[i].len - 1] = 0;
2274 ok( !memcmp( data, bufferA, test_data[i].len ),
2275 "wrong data %.*s\n", test_data[i].len, (char *)data );
2276 }
2277 else
2278 {
2281 if (test_data[i].len >= sizeof(WCHAR))
2282 {
2283 ok( clip == data, "SetClipboardData() returned %p != %p\n", clip, data );
2284 memcpy( bufferW, test_data[i].strW, test_data[i].len );
2285 *((WCHAR *)((char *)bufferW + test_data[i].len) - 1) = 0;
2286 ok( !memcmp( data, bufferW, test_data[i].len ),
2287 "wrong data %s\n", wine_dbgstr_an( data, test_data[i].len ));
2288 }
2289 else
2290 ok( !clip || broken(clip != NULL), "expected SetClipboardData() to fail\n" );
2291 }
2292 r = CloseClipboard();
2293 ok( r, "gle %ld\n", GetLastError() );
2294 sprintf( cmd, "string_data %u", i );
2295 run_process( cmd );
2297 }
2298}
2299
2300static void test_string_data_process( int i )
2301{
2302 BOOL r;
2303 HANDLE data;
2304 UINT len, len2;
2305 char bufferA[12];
2306 WCHAR bufferW[12];
2307
2308 winetest_push_context("%d", i);
2309 r = open_clipboard( 0 );
2310 ok( r, "gle %ld\n", GetLastError() );
2311 if (test_data[i].strA[0])
2312 {
2314 ok( data != 0, "could not get data\n" );
2315 len = GlobalSize( data );
2316 ok( len == test_data[i].len, "wrong size %u / %u\n", len, test_data[i].len );
2317 memcpy( bufferA, test_data[i].strA, test_data[i].len );
2318 bufferA[test_data[i].len - 1] = 0;
2319 ok( !memcmp( data, bufferA, len ), "wrong data %.*s\n", len, (char *)data );
2321 ok( data != 0, "could not get data\n" );
2322 len = GlobalSize( data );
2323 len2 = MultiByteToWideChar( CP_ACP, 0, bufferA, test_data[i].len, bufferW, ARRAY_SIZE(bufferW) );
2324 ok( len == len2 * sizeof(WCHAR), "wrong size %u / %u\n", len, len2 );
2325 ok( !memcmp( data, bufferW, len ), "wrong data %s\n", wine_dbgstr_wn( data, len2 ));
2326 }
2327 else
2328 {
2330 if (!data)
2331 {
2332 ok( test_data[i].len < sizeof(WCHAR), "got no data for len=%d\n", test_data[i].len );
2333 ok( !IsClipboardFormatAvailable( CF_UNICODETEXT ), "unicode available\n" );
2334 }
2335 else if (test_data[i].len == 0)
2336 {
2337 /* 0-byte string handling is broken on Windows <= 10 */
2338 len = GlobalSize( data );
2339 ok( broken(len == 1), "wrong size %u / 0\n", len );
2340 ok( broken(*((char*)data) == 0), "wrong data %s\n", wine_dbgstr_an( data, len ));
2341 }
2342 else
2343 {
2344 len = GlobalSize( data );
2345 ok( len == test_data[i].len, "wrong size %u / %u\n", len, test_data[i].len );
2346 memcpy( bufferW, test_data[i].strW, test_data[i].len );
2347 *((WCHAR *)((char *)bufferW + test_data[i].len) - 1) = 0;
2348 ok( !memcmp( data, bufferW, len ), "wrong data %s\n", wine_dbgstr_an( data, len ));
2349 }
2350
2352 if (test_data[i].len >= sizeof(WCHAR))
2353 {
2354 ok( data != 0, "could not get data\n" );
2355 len = GlobalSize( data );
2356 len2 = WideCharToMultiByte( CP_ACP, 0, bufferW, test_data[i].len / sizeof(WCHAR),
2357 bufferA, ARRAY_SIZE(bufferA), NULL, NULL );
2358 bufferA[len2 - 1] = 0;
2359 ok( len == len2, "wrong size %u / %u\n", len, len2 );
2360 ok( !memcmp( data, bufferA, len ), "wrong data %s, expected %s\n",
2361 wine_dbgstr_an( data, len ), wine_dbgstr_an( bufferA, len2 ));
2362 }
2363 else
2364 {
2366 ok( !available || broken(available /* win10 */),
2367 "available text %d\n", available );
2368 ok( !data, "got data for empty string\n" );
2369 }
2370 }
2371 r = CloseClipboard();
2372 ok( r, "gle %ld\n", GetLastError() );
2374}
2375
2376START_TEST(clipboard)
2377{
2378 char **argv;
2380 HMODULE mod = GetModuleHandleA( "user32" );
2381
2382 argv0 = argv[0];
2383 pAddClipboardFormatListener = (void *)GetProcAddress( mod, "AddClipboardFormatListener" );
2384 pRemoveClipboardFormatListener = (void *)GetProcAddress( mod, "RemoveClipboardFormatListener" );
2385 pGetUpdatedClipboardFormats = (void *)GetProcAddress( mod, "GetUpdatedClipboardFormats" );
2386 pGlobalFree = (void *)GetProcAddress( GetModuleHandleA( "kernel32" ), "GlobalFree" );
2387
2388 if (argc == 4 && !strcmp( argv[2], "set_clipboard_data" ))
2389 {
2391 return;
2392 }
2393 if (argc == 4 && !strcmp( argv[2], "grab_clipboard" ))
2394 {
2396 return;
2397 }
2398 if (argc == 4 && !strcmp( argv[2], "handles" ))
2399 {
2401 return;
2402 }
2403 if (argc == 4 && !strcmp( argv[2], "handles_open" ))
2404 {
2406 return;
2407 }
2408 if (argc == 4 && !strcmp( argv[2], "handles_dib" ))
2409 {
2411 return;
2412 }
2413 if (argc == 4 && !strcmp( argv[2], "string_data" ))
2414 {
2416 return;
2417 }
2418 if (argc == 3 && !strcmp( argv[2], "get_clipboard_data" ))
2419 {
2421 return;
2422 }
2423
2427 test_messages();
2431}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
static POBJECT_TYPE GetObjectType(IN PCWSTR TypeName)
Definition: ObTypes.c:15
void destroy(_Tp *__pointer)
Definition: _construct.h:278
static void startup(void)
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
ATOM WINAPI GlobalFindAtomA(LPCSTR lpString)
Definition: atomansi.c:33
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_METAFILEPICT
Definition: constants.h:398
#define CF_BITMAP
Definition: constants.h:397
#define CF_PALETTE
Definition: constants.h:404
#define CF_DSPENHMETAFILE
Definition: constants.h:417
#define CF_WAVE
Definition: constants.h:407
#define CF_DSPMETAFILEPICT
Definition: constants.h:416
#define CF_LOCALE
Definition: constants.h:411
#define CF_DSPBITMAP
Definition: constants.h:415
#define CF_ENHMETAFILE
Definition: constants.h:409
#define CF_TEXT
Definition: constants.h:396
#define CF_GDIOBJFIRST
Definition: constants.h:420
#define CF_PRIVATEFIRST
Definition: constants.h:418
#define CF_DIB
Definition: constants.h:403
#define CF_RIFF
Definition: constants.h:406
#define CF_OEMTEXT
Definition: constants.h:402
#define ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
static const struct pixel_format_desc formats[]
Definition: util.c:59
static WCHAR available[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2336
const char * wine_dbgstr_an(const char *str, int n)
Definition: compat.c:313
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
HANDLE HWND
Definition: compat.h:19
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
ATOM WINAPI FindAtomA(LPCSTR lpString)
Definition: atom.c:536
UINT WINAPI GetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:557
UINT WINAPI GlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:464
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4104
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
MonoAssembly int argc
Definition: metahost.c:107
const WCHAR * text
Definition: package.c:1794
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1715
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
#define BI_RGB
Definition: precomp.h:44
ULONG RGBQUAD
Definition: precomp.h:47
return ret
Definition: mutex.c:146
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum func
Definition: glext.h:6028
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
#define bits
Definition: infblock.c:15
static TfClientId tid
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
char hdr[14]
Definition: iptest.cpp:33
uint32_t entry
Definition: isohybrid.c:63
static const WCHAR testW[]
Definition: jsregexp.c:44
#define trace_(file, line,...)
Definition: kmt_test.h:226
static real win[4][36]
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
const char * winetest_platform
int winetest_debug
#define win_skip
Definition: minitest.h:67
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE
Definition: minwinbase.h:124
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
static struct test_info tests[]
HWND hWnd1
Definition: button.c:416
HWND hWnd2
Definition: button.c:416
#define sprintf
Definition: sprintf.c:45
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
BOOL expected
Definition: store.c:2000
static DWORD layout
Definition: bitmap.c:46
static UINT wm_drawclipboard
Definition: clipboard.c:1051
static HENHMETAFILE create_emf(void)
Definition: clipboard.c:1532
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: clipboard.c:1053
static HWND next_wnd
Definition: clipboard.c:1050
static const unsigned char metafile[]
Definition: olepicture.c:138
static void test_string_data_process(int i)
Definition: clipboard.c:2300
static DWORD WINAPI open_and_empty_clipboard_thread(LPVOID arg)
Definition: clipboard.c:107
static UINT wm_renderformat
Definition: clipboard.c:1010
static DWORD WINAPI set_clipboard_data_thread(LPVOID arg)
Definition: clipboard.c:123
static BOOL is_fixed(HANDLE handle)
Definition: clipboard.c:1443
static BOOL is_freed(HANDLE handle)
Definition: clipboard.c:1450
static UINT wm_destroyclipboard
Definition: clipboard.c:1009
static DWORD WINAPI test_handles_thread2(void *arg)
Definition: clipboard.c:1742
static DWORD WINAPI clipboard_render_data_thread(void *param)
Definition: clipboard.c:998
static void test_messages(void)
Definition: clipboard.c:1389
static HGLOBAL create_textW(void)
Definition: clipboard.c:552
static BOOL do_render_format
Definition: clipboard.c:1013
static HANDLE update_event
Definition: clipboard.c:1014
static void test_ClipboardOwner(void)
Definition: clipboard.c:279
#define check_messages(a, b, c, d, e, f)
Definition: clipboard.c:1145
static DWORD WINAPI test_handles_thread(void *arg)
Definition: clipboard.c:1735
static void test_data_handles(void)
Definition: clipboard.c:1901
static DWORD WINAPI open_clipboard_thread(LPVOID arg)
Definition: clipboard.c:91
static HBITMAP create_bitmap(void)
Definition: clipboard.c:588
static CRITICAL_SECTION clipboard_cs
Definition: clipboard.c:1005
static HPALETTE palette
Definition: clipboard.c:1457
static LRESULT CALLBACK renderer_winproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: clipboard.c:622
static DWORD WINAPI open_and_empty_clipboard_win_thread(LPVOID arg)
Definition: clipboard.c:115
#define has_no_open_wnd()
Definition: clipboard.c:67
static UINT nb_formats
Definition: clipboard.c:1011
static LRESULT CALLBACK winproc_wrapper(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: clipboard.c:237
static void check_messages_(int line, HWND win, UINT seq_diff, UINT draw, UINT update, UINT destroy, UINT render)
Definition: clipboard.c:1118
static void test_handles_process(const char *str)
Definition: clipboard.c:1793
static const LOGPALETTE logpalette
Definition: clipboard.c:1458
static WNDPROC old_proc
Definition: clipboard.c:236
static UINT format_id
Definition: clipboard.c:1455
static void test_GetUpdatedClipboardFormats(void)
Definition: clipboard.c:2103
static void test_handles_process_open(const char *str)
Definition: clipboard.c:1873
static BOOL open_clipboard_(int line, HWND hwnd)
Definition: clipboard.c:38
static HGLOBAL create_textA(void)
Definition: clipboard.c:543
static HBITMAP create_dib(BOOL v5)
Definition: clipboard.c:596
static HBITMAP bitmap
Definition: clipboard.c:1456
WCHAR strW[12]
Definition: clipboard.c:2216
static HBITMAP bitmap2
Definition: clipboard.c:1456
static void run_process(const char *args)
Definition: clipboard.c:219
static void test_string_data(void)
Definition: clipboard.c:2244
static char * argv0
Definition: clipboard.c:35
char strA[12]
Definition: clipboard.c:2215
static UINT old_seq
Definition: clipboard.c:1116
static DWORD WINAPI clipboard_thread(void *param)
Definition: clipboard.c:1147
static BOOL cross_thread
Definition: clipboard.c:1012
UINT len
Definition: clipboard.c:2217
static BOOL has_no_open_wnd_(int line)
Definition: clipboard.c:68
static void test_RegisterClipboardFormatA(void)
Definition: clipboard.c:426
static void get_clipboard_data_process(void)
Definition: clipboard.c:1103
static void set_clipboard_data_process(int arg)
Definition: clipboard.c:155
static void grab_clipboard_process(int arg)
Definition: clipboard.c:181
#define open_clipboard(hwnd)
Definition: clipboard.c:37
static void test_synthesized(void)
Definition: clipboard.c:640
static UINT wm_clipboardupdate
Definition: clipboard.c:1008
static UINT UINT * out_count
Definition: clipboard.c:31
static void test_handles_process_dib(const char *str)
Definition: clipboard.c:1887
static DWORD WINAPI empty_clipboard_thread(LPVOID arg)
Definition: clipboard.c:98
static int thread_from_line
Definition: clipboard.c:34
static void run_thread(LPTHREAD_START_ROUTINE func, void *arg, int line)
Definition: clipboard.c:197
static HANDLE create_metafile(void)
Definition: clipboard.c:562
static BOOL is_moveable(HANDLE handle)
Definition: clipboard.c:1436
static void test_handles(void)
Definition: monitor.c:2629
#define argv
Definition: mplay32.c:18
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
EXTINLINE DWORD WINAPI GetClipboardSequenceNumber(VOID)
Definition: ntwrapper.h:202
#define OBJ_METAFILE
Definition: objidl.idl:1022
#define OBJ_BITMAP
Definition: objidl.idl:1020
#define OBJ_PAL
Definition: objidl.idl:1018
#define OBJ_ENHMETAFILE
Definition: objidl.idl:1026
#define HGLOBAL
Definition: ole.h:15
#define LOWORD(l)
Definition: pedump.c:82
#define WS_POPUP
Definition: pedump.c:616
WCHAR classname[128]
Definition: startup.c:15
#define test
Definition: rosglue.h:37
#define wine_dbgstr_wn
Definition: testlist.c:2
const WCHAR * str
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_ENGLISH
Definition: nls.h:52
#define SUBLANG_DEFAULT
Definition: nls.h:168
strcpy
Definition: string.h:131
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:187
int winetest_get_mainargs(char ***pargv)
#define wait_child_process
Definition: test.h:159
#define memset(x, y, z)
Definition: compat.h:39
static void render(void)
Definition: ssstars.c:272
& rect
Definition: startmenu.cpp:1413
HINSTANCE hInstance
Definition: winuser.h:3275
LPCSTR lpszClassName
Definition: winuser.h:3280
WNDPROC lpfnWndProc
Definition: winuser.h:3272
Definition: match.c:390
Definition: uimain.c:89
Definition: ftp_var.h:139
Definition: emfdc.c:45
Definition: dsound.c:943
Definition: format.c:58
Definition: parser.c:49
USHORT biBitCount
Definition: precomp.h:34
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidth
Definition: wingdi.h:1868
HMETAFILE hMF
Definition: wingdi.h:3054
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
#define GWLP_WNDPROC
Definition: treelist.c:66
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
UINT WINAPI GetPaletteEntries(HPALETTE hpal, UINT iStartIndex, UINT cEntries, LPPALETTEENTRY ppe)
Definition: palette.c:64
DWORD WINAPI InSendMessageEx(LPVOID lpReserved)
Definition: message.c:1391
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
#define GMEM_ZEROINIT
Definition: winbase.h:330
#define GMEM_FIXED
Definition: winbase.h:317
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define GMEM_MOVEABLE
Definition: winbase.h:318
#define GMEM_DDESHARE
Definition: winbase.h:322
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define ERROR_CLIPBOARD_NOT_OPEN
Definition: winerror.h:1244
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:1226
#define ERROR_NOACCESS
Definition: winerror.h:902
#define ERROR_NOT_FOUND
Definition: winerror.h:1014
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
HDC WINAPI CreateMetaFileA(_In_opt_ LPCSTR)
HPALETTE WINAPI CreatePalette(_In_reads_(_Inexpressible_(2 *sizeof(WORD)+plpal->palNumEntries *sizeof(PALETTEENTRY))) const LOGPALETTE *)
HMETAFILE WINAPI CloseMetaFile(_In_ HDC hdc)
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
HDC WINAPI CreateEnhMetaFileA(_In_opt_ HDC, _In_opt_ LPCSTR, _In_opt_ LPCRECT, _In_opt_ LPCSTR)
#define ETO_OPAQUE
Definition: wingdi.h:647
#define MM_TEXT
Definition: wingdi.h:873
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
#define BITSPIXEL
Definition: wingdi.h:720
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define SetWindowLongPtrA
Definition: winuser.h:5511
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
BOOL WINAPI TranslateMessage(_In_ const MSG *)
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_DESTROYCLIPBOARD
Definition: winuser.h:1896
int WINAPI GetClipboardFormatNameA(_In_ UINT format, _Out_writes_(cchMaxCount) LPSTR lpszFormatName, _In_ int cchMaxCount)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define WM_DRAWCLIPBOARD
Definition: winuser.h:1897
HANDLE WINAPI SetClipboardData(_In_ UINT, _In_opt_ HANDLE)
int WINAPI GetClassNameA(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPSTR lpClassName, _In_ int nMaxCount)
HWND WINAPI GetOpenClipboardWindow(void)
Definition: ntwrapper.h:214
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
HWND WINAPI GetClipboardOwner(void)
Definition: ntwrapper.h:196
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:914
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
UINT WINAPI EnumClipboardFormats(_In_ UINT)
#define WM_CHANGECBCHAIN
Definition: winuser.h:1902
HANDLE WINAPI GetClipboardData(_In_ UINT)
HWND WINAPI SetClipboardViewer(_In_ HWND)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
DWORD WINAPI MsgWaitForMultipleObjectsEx(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask, _In_ DWORD dwFlags)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
BOOL WINAPI ChangeClipboardChain(_In_ HWND, _In_ HWND)
#define PM_REMOVE
Definition: winuser.h:1207
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
HDC WINAPI GetDC(_In_opt_ HWND)
int WINAPI CountClipboardFormats(void)
Definition: ntwrapper.h:184
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define WM_USER
Definition: winuser.h:1923
#define WM_DESTROY
Definition: winuser.h:1637
#define WM_RENDERFORMAT
Definition: winuser.h:1894
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:3014
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_RENDERALLFORMATS
Definition: winuser.h:1895
BOOL WINAPI IsClipboardFormatAvailable(_In_ UINT)
HWND WINAPI GetClipboardViewer(void)
Definition: ntwrapper.h:208
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193