1c2c66affSColin Finck /*
2c2c66affSColin Finck * Unit test suite for clipboard functions.
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2002 Dmitry Timoshkov
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
21d558fc75SAmine Khaldi #include <stdio.h>
22d558fc75SAmine Khaldi #include "wine/test.h"
23d558fc75SAmine Khaldi #include "winbase.h"
24d558fc75SAmine Khaldi #include "winerror.h"
25d558fc75SAmine Khaldi #include "wingdi.h"
26d558fc75SAmine Khaldi #include "winuser.h"
27d558fc75SAmine Khaldi #include "winnls.h"
28c2c66affSColin Finck
29d558fc75SAmine Khaldi #ifdef __REACTOS__
30c2c66affSColin Finck #define WM_CLIPBOARDUPDATE 0x031D
31d558fc75SAmine Khaldi #endif
32c2c66affSColin Finck
33c2c66affSColin Finck static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd);
34c2c66affSColin Finck static BOOL (WINAPI *pRemoveClipboardFormatListener)(HWND hwnd);
35c2c66affSColin Finck static BOOL (WINAPI *pGetUpdatedClipboardFormats)( UINT *formats, UINT count, UINT *out_count );
36c2c66affSColin Finck
37c2c66affSColin Finck static int thread_from_line;
38c2c66affSColin Finck static char *argv0;
39c2c66affSColin Finck
open_clipboard_thread(LPVOID arg)40c2c66affSColin Finck static DWORD WINAPI open_clipboard_thread(LPVOID arg)
41c2c66affSColin Finck {
42c2c66affSColin Finck HWND hWnd = arg;
43c2c66affSColin Finck ok(OpenClipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line);
44c2c66affSColin Finck return 0;
45c2c66affSColin Finck }
46c2c66affSColin Finck
empty_clipboard_thread(LPVOID arg)47c2c66affSColin Finck static DWORD WINAPI empty_clipboard_thread(LPVOID arg)
48c2c66affSColin Finck {
49c2c66affSColin Finck SetLastError( 0xdeadbeef );
50c2c66affSColin Finck ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line );
51c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
52c2c66affSColin Finck thread_from_line, GetLastError());
53c2c66affSColin Finck return 0;
54c2c66affSColin Finck }
55c2c66affSColin Finck
open_and_empty_clipboard_thread(LPVOID arg)56c2c66affSColin Finck static DWORD WINAPI open_and_empty_clipboard_thread(LPVOID arg)
57c2c66affSColin Finck {
58c2c66affSColin Finck HWND hWnd = arg;
59c2c66affSColin Finck ok(OpenClipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line);
60c2c66affSColin Finck ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line );
61c2c66affSColin Finck return 0;
62c2c66affSColin Finck }
63c2c66affSColin Finck
open_and_empty_clipboard_win_thread(LPVOID arg)64c2c66affSColin Finck static DWORD WINAPI open_and_empty_clipboard_win_thread(LPVOID arg)
65c2c66affSColin Finck {
66c2c66affSColin Finck HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
67c2c66affSColin Finck ok(OpenClipboard(hwnd), "%u: OpenClipboard failed\n", thread_from_line);
68c2c66affSColin Finck ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line );
69c2c66affSColin Finck return 0;
70c2c66affSColin Finck }
71c2c66affSColin Finck
set_clipboard_data_thread(LPVOID arg)72c2c66affSColin Finck static DWORD WINAPI set_clipboard_data_thread(LPVOID arg)
73c2c66affSColin Finck {
74c2c66affSColin Finck HWND hwnd = arg;
75c2c66affSColin Finck HANDLE ret;
76c2c66affSColin Finck
77c2c66affSColin Finck SetLastError( 0xdeadbeef );
78c2c66affSColin Finck if (GetClipboardOwner() == hwnd)
79c2c66affSColin Finck {
80c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 );
81c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData failed\n", thread_from_line );
82c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
83c2c66affSColin Finck ok( ret != 0, "%u: SetClipboardData failed err %u\n", thread_from_line, GetLastError() );
84c2c66affSColin Finck SetLastError( 0xdeadbeef );
85c2c66affSColin Finck ret = GetClipboardData( CF_WAVE );
86c2c66affSColin Finck ok( !ret, "%u: GetClipboardData succeeded\n", thread_from_line );
87c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
88c2c66affSColin Finck thread_from_line, GetLastError());
89c2c66affSColin Finck }
90c2c66affSColin Finck else
91c2c66affSColin Finck {
92c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 );
93c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
94c2c66affSColin Finck thread_from_line, GetLastError());
95c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line );
96c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
97c2c66affSColin Finck ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line );
98c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
99c2c66affSColin Finck thread_from_line, GetLastError());
100c2c66affSColin Finck }
101c2c66affSColin Finck return 0;
102c2c66affSColin Finck }
103c2c66affSColin Finck
set_clipboard_data_process(int arg)104c2c66affSColin Finck static void set_clipboard_data_process( int arg )
105c2c66affSColin Finck {
106c2c66affSColin Finck HANDLE ret;
107c2c66affSColin Finck
108c2c66affSColin Finck SetLastError( 0xdeadbeef );
109c2c66affSColin Finck if (arg)
110c2c66affSColin Finck {
111c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "process %u: CF_WAVE not available\n", arg );
112c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
113c2c66affSColin Finck ok( ret != 0, "process %u: SetClipboardData failed err %u\n", arg, GetLastError() );
114c2c66affSColin Finck }
115c2c66affSColin Finck else
116c2c66affSColin Finck {
117c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 );
118c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n",
119c2c66affSColin Finck arg, GetLastError());
120c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "process %u: SetClipboardData succeeded\n", arg );
121c2c66affSColin Finck ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
122c2c66affSColin Finck ok( !ret, "process %u: SetClipboardData succeeded\n", arg );
123c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n",
124c2c66affSColin Finck arg, GetLastError());
125c2c66affSColin Finck }
126c2c66affSColin Finck }
127c2c66affSColin Finck
grab_clipboard_process(int arg)128c2c66affSColin Finck static void grab_clipboard_process( int arg )
129c2c66affSColin Finck {
130c2c66affSColin Finck BOOL ret;
131c2c66affSColin Finck
132c2c66affSColin Finck SetLastError( 0xdeadbeef );
133c2c66affSColin Finck ret = OpenClipboard( 0 );
134c2c66affSColin Finck ok( ret, "OpenClipboard failed\n" );
135c2c66affSColin Finck ret = EmptyClipboard();
136c2c66affSColin Finck ok( ret, "EmptyClipboard failed\n" );
137c2c66affSColin Finck if (arg)
138c2c66affSColin Finck {
139c2c66affSColin Finck HANDLE ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
140c2c66affSColin Finck ok( ret != 0, "process %u: SetClipboardData failed err %u\n", arg, GetLastError() );
141c2c66affSColin Finck }
142c2c66affSColin Finck }
143c2c66affSColin Finck
run_thread(LPTHREAD_START_ROUTINE func,void * arg,int line)144c2c66affSColin Finck static void run_thread( LPTHREAD_START_ROUTINE func, void *arg, int line )
145c2c66affSColin Finck {
146c2c66affSColin Finck DWORD ret;
147c2c66affSColin Finck HANDLE thread;
148c2c66affSColin Finck
149c2c66affSColin Finck thread_from_line = line;
150c2c66affSColin Finck thread = CreateThread(NULL, 0, func, arg, 0, NULL);
151c2c66affSColin Finck ok(thread != NULL, "%u: CreateThread failed with error %d\n", line, GetLastError());
152c2c66affSColin Finck for (;;)
153c2c66affSColin Finck {
154c2c66affSColin Finck ret = MsgWaitForMultipleObjectsEx( 1, &thread, 1000, QS_ALLINPUT, 0 );
155c2c66affSColin Finck if (ret == WAIT_OBJECT_0 + 1)
156c2c66affSColin Finck {
157c2c66affSColin Finck MSG msg;
158c2c66affSColin Finck while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
159c2c66affSColin Finck }
160c2c66affSColin Finck else break;
161c2c66affSColin Finck }
162c2c66affSColin Finck ok(ret == WAIT_OBJECT_0, "%u: expected WAIT_OBJECT_0, got %u\n", line, ret);
163c2c66affSColin Finck CloseHandle(thread);
164c2c66affSColin Finck }
165c2c66affSColin Finck
run_process(const char * args)166c2c66affSColin Finck static void run_process( const char *args )
167c2c66affSColin Finck {
168c2c66affSColin Finck char cmd[MAX_PATH];
169c2c66affSColin Finck PROCESS_INFORMATION info;
170c2c66affSColin Finck STARTUPINFOA startup;
171c2c66affSColin Finck
172c2c66affSColin Finck sprintf( cmd, "%s clipboard %s", argv0, args );
173c2c66affSColin Finck memset( &startup, 0, sizeof(startup) );
174c2c66affSColin Finck startup.cb = sizeof(startup);
175c2c66affSColin Finck ok( CreateProcessA( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ),
176c2c66affSColin Finck "CreateProcess %s failed\n", cmd );
177c2c66affSColin Finck
178c2c66affSColin Finck winetest_wait_child_process( info.hProcess );
179c2c66affSColin Finck CloseHandle( info.hProcess );
180c2c66affSColin Finck CloseHandle( info.hThread );
181c2c66affSColin Finck }
182c2c66affSColin Finck
183c2c66affSColin Finck static WNDPROC old_proc;
winproc_wrapper(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)184c2c66affSColin Finck static LRESULT CALLBACK winproc_wrapper( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
185c2c66affSColin Finck {
186c2c66affSColin Finck static int wm_renderallformats;
187c2c66affSColin Finck static int wm_drawclipboard;
188c2c66affSColin Finck static int seqno;
189c2c66affSColin Finck DWORD msg_flags = InSendMessageEx( NULL );
190c2c66affSColin Finck
191c2c66affSColin Finck if (!seqno) seqno = GetClipboardSequenceNumber();
192c2c66affSColin Finck
193c2c66affSColin Finck trace( "%p msg %04x\n", hwnd, msg );
194c2c66affSColin Finck if (!wm_renderallformats)
195c2c66affSColin Finck {
196c2c66affSColin Finck ok( GetClipboardOwner() == hwnd, "%04x: wrong owner %p/%p\n", msg, GetClipboardOwner(), hwnd );
197c2c66affSColin Finck ok( seqno == GetClipboardSequenceNumber(), "%04x: seqno changed\n", msg );
198c2c66affSColin Finck }
199c2c66affSColin Finck else
200c2c66affSColin Finck {
201c2c66affSColin Finck ok( !GetClipboardOwner(), "%04x: wrong owner %p\n", msg, GetClipboardOwner() );
202c2c66affSColin Finck ok( seqno + 1 == GetClipboardSequenceNumber(), "%04x: seqno unchanged\n", msg );
203c2c66affSColin Finck }
204c2c66affSColin Finck ok( GetClipboardViewer() == hwnd, "%04x: wrong viewer %p/%p\n", msg, GetClipboardViewer(), hwnd );
205c2c66affSColin Finck ok( GetOpenClipboardWindow() == hwnd, "%04x: wrong open win %p/%p\n",
206c2c66affSColin Finck msg, GetOpenClipboardWindow(), hwnd );
207c2c66affSColin Finck
208c2c66affSColin Finck switch (msg)
209c2c66affSColin Finck {
210c2c66affSColin Finck case WM_DESTROY:
211c2c66affSColin Finck ok( wm_renderallformats, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
212c2c66affSColin Finck ok( wm_drawclipboard, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
213c2c66affSColin Finck break;
214c2c66affSColin Finck case WM_DRAWCLIPBOARD:
215c2c66affSColin Finck ok( msg_flags == ISMEX_NOSEND, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags );
216c2c66affSColin Finck wm_drawclipboard++;
217c2c66affSColin Finck break;
218c2c66affSColin Finck case WM_RENDERALLFORMATS:
219c2c66affSColin Finck ok( msg_flags == ISMEX_NOSEND, "WM_RENDERALLFORMATS wrong flags %x\n", msg_flags );
220c2c66affSColin Finck wm_renderallformats++;
221c2c66affSColin Finck break;
222c2c66affSColin Finck }
223c2c66affSColin Finck return old_proc( hwnd, msg, wp, lp );
224c2c66affSColin Finck }
225c2c66affSColin Finck
test_ClipboardOwner(void)226c2c66affSColin Finck static void test_ClipboardOwner(void)
227c2c66affSColin Finck {
228c2c66affSColin Finck HWND hWnd1, hWnd2;
229c2c66affSColin Finck BOOL ret;
230c2c66affSColin Finck
231c2c66affSColin Finck SetLastError(0xdeadbeef);
232c2c66affSColin Finck ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
233c2c66affSColin Finck "could not perform clipboard test: clipboard already owned\n");
234c2c66affSColin Finck
235c2c66affSColin Finck hWnd1 = CreateWindowExA(0, "static", NULL, WS_POPUP,
236c2c66affSColin Finck 0, 0, 10, 10, 0, 0, 0, NULL);
237c2c66affSColin Finck ok(hWnd1 != 0, "CreateWindowExA error %d\n", GetLastError());
238c2c66affSColin Finck trace("hWnd1 = %p\n", hWnd1);
239c2c66affSColin Finck
240c2c66affSColin Finck hWnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP,
241c2c66affSColin Finck 0, 0, 10, 10, 0, 0, 0, NULL);
242c2c66affSColin Finck ok(hWnd2 != 0, "CreateWindowExA error %d\n", GetLastError());
243c2c66affSColin Finck trace("hWnd2 = %p\n", hWnd2);
244c2c66affSColin Finck
245c2c66affSColin Finck SetLastError(0xdeadbeef);
246c2c66affSColin Finck ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
247c2c66affSColin Finck ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */
248c2c66affSColin Finck "wrong error %u\n", GetLastError());
249c2c66affSColin Finck
250c2c66affSColin Finck ok(OpenClipboard(0), "OpenClipboard failed\n");
251c2c66affSColin Finck ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
252c2c66affSColin Finck ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n");
253c2c66affSColin Finck ok(OpenClipboard(0), "OpenClipboard again failed\n");
254c2c66affSColin Finck ret = CloseClipboard();
255c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError());
256c2c66affSColin Finck
257c2c66affSColin Finck ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
258c2c66affSColin Finck run_thread( open_clipboard_thread, hWnd1, __LINE__ );
259c2c66affSColin Finck run_thread( empty_clipboard_thread, 0, __LINE__ );
260c2c66affSColin Finck run_thread( set_clipboard_data_thread, hWnd1, __LINE__ );
261c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE available\n" );
262c2c66affSColin Finck ok( !GetClipboardData( CF_WAVE ), "CF_WAVE data available\n" );
263c2c66affSColin Finck run_process( "set_clipboard_data 0" );
264c2c66affSColin Finck ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
265c2c66affSColin Finck ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
266c2c66affSColin Finck
267c2c66affSColin Finck SetLastError(0xdeadbeef);
268c2c66affSColin Finck ret = OpenClipboard(hWnd2);
269c2c66affSColin Finck ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
270c2c66affSColin Finck "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
271c2c66affSColin Finck
272c2c66affSColin Finck SetLastError(0xdeadbeef);
273c2c66affSColin Finck ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
274c2c66affSColin Finck ret = EmptyClipboard();
275c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError());
276c2c66affSColin Finck ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner());
277c2c66affSColin Finck run_thread( empty_clipboard_thread, 0, __LINE__ );
278c2c66affSColin Finck run_thread( set_clipboard_data_thread, hWnd1, __LINE__ );
279c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
280c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
281c2c66affSColin Finck run_process( "set_clipboard_data 1" );
282c2c66affSColin Finck
283c2c66affSColin Finck SetLastError(0xdeadbeef);
284c2c66affSColin Finck ret = OpenClipboard(hWnd2);
285c2c66affSColin Finck ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
286c2c66affSColin Finck "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
287c2c66affSColin Finck
288c2c66affSColin Finck ret = CloseClipboard();
289c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError());
290c2c66affSColin Finck ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n");
291c2c66affSColin Finck
292c2c66affSColin Finck /* any window will do, even from a different process */
293c2c66affSColin Finck ret = OpenClipboard( GetDesktopWindow() );
294c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError());
295c2c66affSColin Finck ret = EmptyClipboard();
296c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError());
297c2c66affSColin Finck ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
298c2c66affSColin Finck GetClipboardOwner(), GetDesktopWindow() );
299c2c66affSColin Finck run_thread( set_clipboard_data_thread, GetDesktopWindow(), __LINE__ );
300c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
301c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
302c2c66affSColin Finck run_process( "set_clipboard_data 2" );
303c2c66affSColin Finck ret = CloseClipboard();
304c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError());
305c2c66affSColin Finck
306c2c66affSColin Finck ret = OpenClipboard( hWnd1 );
307c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError());
308c2c66affSColin Finck ret = EmptyClipboard();
309c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError());
310c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 );
311c2c66affSColin Finck SetClipboardViewer( hWnd1 );
312c2c66affSColin Finck ok( GetClipboardOwner() == hWnd1, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1 );
313c2c66affSColin Finck ok( GetClipboardViewer() == hWnd1, "wrong viewer %p/%p\n", GetClipboardViewer(), hWnd1 );
314c2c66affSColin Finck ok( GetOpenClipboardWindow() == hWnd1, "wrong open win %p/%p\n", GetOpenClipboardWindow(), hWnd1 );
315c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
316c2c66affSColin Finck
317c2c66affSColin Finck old_proc = (WNDPROC)SetWindowLongPtrA( hWnd1, GWLP_WNDPROC, (LONG_PTR)winproc_wrapper );
318c2c66affSColin Finck ret = DestroyWindow(hWnd1);
319c2c66affSColin Finck ok( ret, "DestroyWindow error %d\n", GetLastError());
320c2c66affSColin Finck ret = DestroyWindow(hWnd2);
321c2c66affSColin Finck ok( ret, "DestroyWindow error %d\n", GetLastError());
322c2c66affSColin Finck SetLastError(0xdeadbeef);
323c2c66affSColin Finck ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
324c2c66affSColin Finck ok(!GetClipboardViewer() && GetLastError() == 0xdeadbeef, "viewer still exists\n");
325c2c66affSColin Finck ok(!GetOpenClipboardWindow() && GetLastError() == 0xdeadbeef, "clipboard should not be open\n");
326c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE available\n" );
327c2c66affSColin Finck
328c2c66affSColin Finck SetLastError( 0xdeadbeef );
329c2c66affSColin Finck ret = CloseClipboard();
330c2c66affSColin Finck ok( !ret, "CloseClipboard succeeded\n" );
331c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() );
332c2c66affSColin Finck
333c2c66affSColin Finck ret = OpenClipboard( 0 );
334c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError());
335c2c66affSColin Finck run_thread( set_clipboard_data_thread, 0, __LINE__ );
336c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
337c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
338c2c66affSColin Finck run_process( "set_clipboard_data 3" );
339c2c66affSColin Finck ret = CloseClipboard();
340c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError());
341c2c66affSColin Finck
342c2c66affSColin Finck run_thread( open_and_empty_clipboard_thread, 0, __LINE__ );
343c2c66affSColin Finck ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
344c2c66affSColin Finck ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
345c2c66affSColin Finck
346c2c66affSColin Finck ret = OpenClipboard( 0 );
347c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError());
348c2c66affSColin Finck run_thread( set_clipboard_data_thread, 0, __LINE__ );
349c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_WAVE ), "CF_WAVE not available\n" );
350c2c66affSColin Finck ok( GetClipboardData( CF_WAVE ) != 0, "CF_WAVE data not available\n" );
351c2c66affSColin Finck run_process( "set_clipboard_data 4" );
352c2c66affSColin Finck ret = EmptyClipboard();
353c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError());
354c2c66affSColin Finck ret = CloseClipboard();
355c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError());
356c2c66affSColin Finck
357c2c66affSColin Finck SetLastError( 0xdeadbeef );
358c2c66affSColin Finck ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )),
359c2c66affSColin Finck "SetClipboardData succeeded\n" );
360c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() );
361c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" );
362c2c66affSColin Finck
363c2c66affSColin Finck run_thread( open_and_empty_clipboard_thread, GetDesktopWindow(), __LINE__ );
364c2c66affSColin Finck ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
365c2c66affSColin Finck ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner window %p / %p\n",
366c2c66affSColin Finck GetClipboardOwner(), GetDesktopWindow() );
367c2c66affSColin Finck
368c2c66affSColin Finck run_thread( open_and_empty_clipboard_win_thread, 0, __LINE__ );
369c2c66affSColin Finck ok( !GetOpenClipboardWindow(), "wrong open window %p\n", GetOpenClipboardWindow() );
370c2c66affSColin Finck ok( !GetClipboardOwner(), "wrong owner window %p\n", GetClipboardOwner() );
371c2c66affSColin Finck }
372c2c66affSColin Finck
test_RegisterClipboardFormatA(void)373c2c66affSColin Finck static void test_RegisterClipboardFormatA(void)
374c2c66affSColin Finck {
375c2c66affSColin Finck ATOM atom_id;
376c2c66affSColin Finck UINT format_id, format_id2;
377c2c66affSColin Finck char buf[256];
378c2c66affSColin Finck int len;
379c2c66affSColin Finck BOOL ret;
380c2c66affSColin Finck HANDLE handle;
381c2c66affSColin Finck
382c2c66affSColin Finck format_id = RegisterClipboardFormatA("my_cool_clipboard_format");
383c2c66affSColin Finck ok(format_id > 0xc000 && format_id < 0xffff, "invalid clipboard format id %04x\n", format_id);
384c2c66affSColin Finck
385c2c66affSColin Finck format_id2 = RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
386c2c66affSColin Finck ok(format_id2 == format_id, "invalid clipboard format id %04x\n", format_id2);
387c2c66affSColin Finck
388c2c66affSColin Finck len = GetClipboardFormatNameA(format_id, buf, 256);
389c2c66affSColin Finck ok(len == lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len);
390c2c66affSColin Finck ok(!lstrcmpA(buf, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf);
391c2c66affSColin Finck
392d558fc75SAmine Khaldi len = GetClipboardFormatNameA(format_id, NULL, 0);
393d558fc75SAmine Khaldi ok(len == 0, "wrong format name length %d\n", len);
394d558fc75SAmine Khaldi
395c2c66affSColin Finck lstrcpyA(buf, "foo");
396c2c66affSColin Finck SetLastError(0xdeadbeef);
397c2c66affSColin Finck len = GetAtomNameA((ATOM)format_id, buf, 256);
398c2c66affSColin Finck ok(len == 0, "GetAtomNameA should fail\n");
399c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "err %d\n", GetLastError());
400c2c66affSColin Finck
401c2c66affSColin Finck todo_wine
402c2c66affSColin Finck {
403c2c66affSColin Finck lstrcpyA(buf, "foo");
404c2c66affSColin Finck SetLastError(0xdeadbeef);
405c2c66affSColin Finck len = GlobalGetAtomNameA((ATOM)format_id, buf, 256);
406c2c66affSColin Finck ok(len == 0, "GlobalGetAtomNameA should fail\n");
407c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_HANDLE, "err %d\n", GetLastError());
408c2c66affSColin Finck }
409c2c66affSColin Finck
410c2c66affSColin Finck SetLastError(0xdeadbeef);
411c2c66affSColin Finck atom_id = FindAtomA("my_cool_clipboard_format");
412c2c66affSColin Finck ok(atom_id == 0, "FindAtomA should fail\n");
413c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %d\n", GetLastError());
414c2c66affSColin Finck
415c2c66affSColin Finck if (0)
416c2c66affSColin Finck {
417c2c66affSColin Finck /* this relies on the clipboard and global atom table being different */
418c2c66affSColin Finck SetLastError(0xdeadbeef);
419c2c66affSColin Finck atom_id = GlobalFindAtomA("my_cool_clipboard_format");
420c2c66affSColin Finck ok(atom_id == 0, "GlobalFindAtomA should fail\n");
421c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %d\n", GetLastError());
422c2c66affSColin Finck }
423c2c66affSColin Finck
424c2c66affSColin Finck for (format_id = 0; format_id < 0x10fff; format_id++)
425c2c66affSColin Finck {
426c2c66affSColin Finck SetLastError(0xdeadbeef);
427c2c66affSColin Finck len = GetClipboardFormatNameA(format_id, buf, 256);
428c2c66affSColin Finck
429c2c66affSColin Finck if (format_id < 0xc000 || format_id > 0xffff)
430c2c66affSColin Finck ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf);
431c2c66affSColin Finck else if (len && winetest_debug > 1)
432c2c66affSColin Finck trace("%04x: %s\n", format_id, len ? buf : "");
433c2c66affSColin Finck }
434c2c66affSColin Finck
435c2c66affSColin Finck ret = OpenClipboard(0);
436c2c66affSColin Finck ok( ret, "OpenClipboard error %d\n", GetLastError());
437c2c66affSColin Finck
438c2c66affSColin Finck /* try some invalid/unregistered formats */
439c2c66affSColin Finck SetLastError( 0xdeadbeef );
440c2c66affSColin Finck handle = SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
441c2c66affSColin Finck ok( !handle, "SetClipboardData succeeded\n" );
442c2c66affSColin Finck ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError());
443c2c66affSColin Finck handle = SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
444c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError());
445c2c66affSColin Finck handle = SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
446c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError());
447c2c66affSColin Finck handle = SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
448c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError());
449c2c66affSColin Finck
450c2c66affSColin Finck ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
451c2c66affSColin Finck ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
452c2c66affSColin Finck ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
453c2c66affSColin Finck ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
454c2c66affSColin Finck ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
455c2c66affSColin Finck ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
456c2c66affSColin Finck
457c2c66affSColin Finck trace("# of formats available: %d\n", CountClipboardFormats());
458c2c66affSColin Finck
459c2c66affSColin Finck format_id = 0;
460c2c66affSColin Finck while ((format_id = EnumClipboardFormats(format_id)))
461c2c66affSColin Finck {
462c2c66affSColin Finck ok(IsClipboardFormatAvailable(format_id), "format %04x was listed as available\n", format_id);
463c2c66affSColin Finck len = GetClipboardFormatNameA(format_id, buf, 256);
464c2c66affSColin Finck trace("%04x: %s\n", format_id, len ? buf : "");
465c2c66affSColin Finck }
466c2c66affSColin Finck
467c2c66affSColin Finck ret = EmptyClipboard();
468c2c66affSColin Finck ok( ret, "EmptyClipboard error %d\n", GetLastError());
469c2c66affSColin Finck ret =CloseClipboard();
470c2c66affSColin Finck ok( ret, "CloseClipboard error %d\n", GetLastError());
471c2c66affSColin Finck
472c2c66affSColin Finck if (CountClipboardFormats())
473c2c66affSColin Finck {
474c2c66affSColin Finck SetLastError(0xdeadbeef);
475c2c66affSColin Finck ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
476c2c66affSColin Finck ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN,
477c2c66affSColin Finck "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %d\n", GetLastError());
478c2c66affSColin Finck }
479c2c66affSColin Finck
480c2c66affSColin Finck SetLastError(0xdeadbeef);
481c2c66affSColin Finck ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
482c2c66affSColin Finck ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */
483c2c66affSColin Finck "Wrong error %u\n", GetLastError());
484c2c66affSColin Finck
485c2c66affSColin Finck format_id = RegisterClipboardFormatA("#1234");
486c2c66affSColin Finck ok(format_id == 1234, "invalid clipboard format id %04x\n", format_id);
487c2c66affSColin Finck }
488c2c66affSColin Finck
create_textA(void)489c2c66affSColin Finck static HGLOBAL create_textA(void)
490c2c66affSColin Finck {
491c2c66affSColin Finck HGLOBAL h = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, 10);
492c2c66affSColin Finck char *p = GlobalLock(h);
493c2c66affSColin Finck memcpy(p, "test\0\0\0\0\0", 10);
494c2c66affSColin Finck GlobalUnlock(h);
495c2c66affSColin Finck return h;
496c2c66affSColin Finck }
497c2c66affSColin Finck
create_textW(void)498c2c66affSColin Finck static HGLOBAL create_textW(void)
499c2c66affSColin Finck {
500c2c66affSColin Finck static const WCHAR testW[] = {'t','e','s','t',0,0,0,0,0,0};
501c2c66affSColin Finck HGLOBAL h = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, sizeof(testW));
502c2c66affSColin Finck WCHAR *p = GlobalLock(h);
503c2c66affSColin Finck memcpy(p, testW, sizeof(testW));
504c2c66affSColin Finck GlobalUnlock(h);
505c2c66affSColin Finck return h;
506c2c66affSColin Finck }
507c2c66affSColin Finck
create_metafile(void)508c2c66affSColin Finck static HANDLE create_metafile(void)
509c2c66affSColin Finck {
510c2c66affSColin Finck const RECT rect = {0, 0, 100, 100};
511c2c66affSColin Finck METAFILEPICT *pict;
512c2c66affSColin Finck HANDLE ret;
513c2c66affSColin Finck HMETAFILE mf;
514c2c66affSColin Finck HDC hdc = CreateMetaFileA( NULL );
515c2c66affSColin Finck ExtTextOutA( hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL );
516c2c66affSColin Finck mf = CloseMetaFile( hdc );
517c2c66affSColin Finck ret = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(*pict) );
518c2c66affSColin Finck pict = GlobalLock( ret );
519c2c66affSColin Finck pict->mm = MM_TEXT;
520c2c66affSColin Finck pict->xExt = pict->yExt = 100;
521c2c66affSColin Finck pict->hMF = mf;
522c2c66affSColin Finck GlobalUnlock( ret );
523c2c66affSColin Finck return ret;
524c2c66affSColin Finck }
525c2c66affSColin Finck
create_emf(void)526c2c66affSColin Finck static HENHMETAFILE create_emf(void)
527c2c66affSColin Finck {
528c2c66affSColin Finck const RECT rect = {0, 0, 100, 100};
529c2c66affSColin Finck HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
530c2c66affSColin Finck ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
531c2c66affSColin Finck return CloseEnhMetaFile(hdc);
532c2c66affSColin Finck }
533c2c66affSColin Finck
create_bitmap(void)534c2c66affSColin Finck static HBITMAP create_bitmap(void)
535c2c66affSColin Finck {
536c2c66affSColin Finck HDC hdc = GetDC( 0 );
537c2c66affSColin Finck UINT bpp = GetDeviceCaps( hdc, BITSPIXEL );
538c2c66affSColin Finck ReleaseDC( 0, hdc );
539c2c66affSColin Finck return CreateBitmap( 10, 10, 1, bpp, NULL );
540c2c66affSColin Finck }
541c2c66affSColin Finck
create_dib(BOOL v5)542c2c66affSColin Finck static HBITMAP create_dib( BOOL v5 )
543c2c66affSColin Finck {
544c2c66affSColin Finck HANDLE ret;
545c2c66affSColin Finck BITMAPINFOHEADER *hdr;
546c2c66affSColin Finck
547c2c66affSColin Finck ret = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
548c2c66affSColin Finck sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD) + 16 * 16 * 4 );
549c2c66affSColin Finck hdr = GlobalLock( ret );
550c2c66affSColin Finck hdr->biSize = v5 ? sizeof(BITMAPV5HEADER) : sizeof(*hdr);
551c2c66affSColin Finck hdr->biWidth = 16;
552c2c66affSColin Finck hdr->biHeight = 16;
553c2c66affSColin Finck hdr->biPlanes = 1;
554c2c66affSColin Finck hdr->biBitCount = 32;
555c2c66affSColin Finck hdr->biCompression = BI_RGB;
556c2c66affSColin Finck if (v5)
557c2c66affSColin Finck {
558c2c66affSColin Finck BITMAPV5HEADER *hdr5 = (BITMAPV5HEADER *)hdr;
559c2c66affSColin Finck hdr5->bV5RedMask = 0x0000ff;
560c2c66affSColin Finck hdr5->bV5GreenMask = 0x00ff00;
561c2c66affSColin Finck hdr5->bV5BlueMask = 0xff0000;
562c2c66affSColin Finck hdr5->bV5AlphaMask = 0xff000000;
563c2c66affSColin Finck }
564c2c66affSColin Finck GlobalUnlock( ret );
565c2c66affSColin Finck return ret;
566c2c66affSColin Finck }
567c2c66affSColin Finck
renderer_winproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)568c2c66affSColin Finck static LRESULT CALLBACK renderer_winproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
569c2c66affSColin Finck {
570c2c66affSColin Finck static UINT rendered;
571c2c66affSColin Finck UINT ret;
572c2c66affSColin Finck
573c2c66affSColin Finck switch (msg)
574c2c66affSColin Finck {
575c2c66affSColin Finck case WM_RENDERFORMAT:
576c2c66affSColin Finck if (wp < 32) rendered |= (1 << wp);
577c2c66affSColin Finck break;
578c2c66affSColin Finck case WM_USER:
579c2c66affSColin Finck ret = rendered;
580c2c66affSColin Finck rendered = 0;
581c2c66affSColin Finck return ret;
582c2c66affSColin Finck }
583c2c66affSColin Finck return DefWindowProcA( hwnd, msg, wp, lp );
584c2c66affSColin Finck }
585c2c66affSColin Finck
test_synthesized(void)586c2c66affSColin Finck static void test_synthesized(void)
587c2c66affSColin Finck {
588c2c66affSColin Finck static const struct test
589c2c66affSColin Finck {
590c2c66affSColin Finck UINT format;
591c2c66affSColin Finck UINT expected[8];
592c2c66affSColin Finck } tests[] =
593c2c66affSColin Finck {
594c2c66affSColin Finck /* 0 */ { CF_TEXT, { CF_TEXT, CF_LOCALE, CF_OEMTEXT, CF_UNICODETEXT }},
595c2c66affSColin Finck { CF_OEMTEXT, { CF_OEMTEXT, CF_LOCALE, CF_TEXT, CF_UNICODETEXT }},
596c2c66affSColin Finck { CF_UNICODETEXT, { CF_UNICODETEXT, CF_LOCALE, CF_TEXT, CF_OEMTEXT }},
597c2c66affSColin Finck { CF_ENHMETAFILE, { CF_ENHMETAFILE, CF_METAFILEPICT }},
598c2c66affSColin Finck { CF_METAFILEPICT, { CF_METAFILEPICT, CF_ENHMETAFILE }},
599c2c66affSColin Finck /* 5 */ { CF_BITMAP, { CF_BITMAP, CF_DIB, CF_DIBV5 }},
600c2c66affSColin Finck { CF_DIB, { CF_DIB, CF_BITMAP, CF_DIBV5 }},
601c2c66affSColin Finck { CF_DIBV5, { CF_DIBV5, CF_BITMAP, CF_DIB }},
602c2c66affSColin Finck };
603c2c66affSColin Finck
604c2c66affSColin Finck HGLOBAL h, htext;
605c2c66affSColin Finck HENHMETAFILE emf;
606c2c66affSColin Finck BOOL r;
607c2c66affSColin Finck UINT cf, i, j, count, rendered, seq, old_seq;
608c2c66affSColin Finck HANDLE data;
609c2c66affSColin Finck HWND hwnd;
610c2c66affSColin Finck
611c2c66affSColin Finck hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
612c2c66affSColin Finck SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)renderer_winproc );
613c2c66affSColin Finck
614c2c66affSColin Finck htext = create_textA();
615c2c66affSColin Finck emf = create_emf();
616c2c66affSColin Finck
617c2c66affSColin Finck r = OpenClipboard(NULL);
618c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
619c2c66affSColin Finck r = EmptyClipboard();
620c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
621c2c66affSColin Finck h = SetClipboardData(CF_TEXT, htext);
622c2c66affSColin Finck ok(h == htext, "got %p\n", h);
623c2c66affSColin Finck h = SetClipboardData(CF_ENHMETAFILE, emf);
624c2c66affSColin Finck ok(h == emf, "got %p\n", h);
625c2c66affSColin Finck r = CloseClipboard();
626c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
627c2c66affSColin Finck
628c2c66affSColin Finck count = CountClipboardFormats();
629c2c66affSColin Finck ok( count == 6, "count %u\n", count );
630c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_TEXT );
631c2c66affSColin Finck ok( r, "CF_TEXT not available err %d\n", GetLastError());
632c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_LOCALE );
633c2c66affSColin Finck ok( r, "CF_LOCALE not available err %d\n", GetLastError());
634c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_OEMTEXT );
635c2c66affSColin Finck ok( r, "CF_OEMTEXT not available err %d\n", GetLastError());
636c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_UNICODETEXT );
637c2c66affSColin Finck ok( r, "CF_UNICODETEXT not available err %d\n", GetLastError());
638c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_ENHMETAFILE );
639c2c66affSColin Finck ok( r, "CF_ENHMETAFILE not available err %d\n", GetLastError());
640c2c66affSColin Finck r = IsClipboardFormatAvailable( CF_METAFILEPICT );
641c2c66affSColin Finck ok( r, "CF_METAFILEPICT not available err %d\n", GetLastError());
642c2c66affSColin Finck
643c2c66affSColin Finck r = OpenClipboard(NULL);
644c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
645c2c66affSColin Finck cf = EnumClipboardFormats(0);
646c2c66affSColin Finck ok(cf == CF_TEXT, "cf %08x\n", cf);
647c2c66affSColin Finck data = GetClipboardData(cf);
648c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf);
649c2c66affSColin Finck
650c2c66affSColin Finck cf = EnumClipboardFormats(cf);
651c2c66affSColin Finck ok(cf == CF_ENHMETAFILE, "cf %08x\n", cf);
652c2c66affSColin Finck data = GetClipboardData(cf);
653c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf);
654c2c66affSColin Finck
655c2c66affSColin Finck cf = EnumClipboardFormats(cf);
656c2c66affSColin Finck ok(cf == CF_LOCALE, "cf %08x\n", cf);
657c2c66affSColin Finck data = GetClipboardData(cf);
658c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf);
659c2c66affSColin Finck
660c2c66affSColin Finck cf = EnumClipboardFormats(cf);
661c2c66affSColin Finck ok(cf == CF_OEMTEXT, "cf %08x\n", cf);
662c2c66affSColin Finck data = GetClipboardData(cf);
663c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf);
664c2c66affSColin Finck
665c2c66affSColin Finck cf = EnumClipboardFormats(cf);
666c2c66affSColin Finck ok(cf == CF_UNICODETEXT, "cf %08x\n", cf);
667c2c66affSColin Finck
668c2c66affSColin Finck cf = EnumClipboardFormats(cf);
669c2c66affSColin Finck ok(cf == CF_METAFILEPICT, "cf %08x\n", cf);
670c2c66affSColin Finck data = GetClipboardData(cf);
671c2c66affSColin Finck ok(data != NULL, "couldn't get data, cf %08x\n", cf);
672c2c66affSColin Finck
673c2c66affSColin Finck cf = EnumClipboardFormats(cf);
674c2c66affSColin Finck ok(cf == 0, "cf %08x\n", cf);
675c2c66affSColin Finck
676c2c66affSColin Finck r = EmptyClipboard();
677c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
678c2c66affSColin Finck
679c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, create_textW() );
680c2c66affSColin Finck SetClipboardData( CF_TEXT, create_textA() );
681c2c66affSColin Finck SetClipboardData( CF_OEMTEXT, create_textA() );
682c2c66affSColin Finck r = CloseClipboard();
683c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
684c2c66affSColin Finck
685c2c66affSColin Finck r = OpenClipboard( NULL );
686c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
687c2c66affSColin Finck SetLastError( 0xdeadbeef );
688c2c66affSColin Finck cf = EnumClipboardFormats(0);
689c2c66affSColin Finck ok( cf == CF_UNICODETEXT, "cf %08x\n", cf );
690c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() );
691c2c66affSColin Finck SetLastError( 0xdeadbeef );
692c2c66affSColin Finck cf = EnumClipboardFormats(cf);
693c2c66affSColin Finck ok( cf == CF_TEXT, "cf %08x\n", cf );
694c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() );
695c2c66affSColin Finck SetLastError( 0xdeadbeef );
696c2c66affSColin Finck cf = EnumClipboardFormats(cf);
697c2c66affSColin Finck ok( cf == CF_OEMTEXT, "cf %08x\n", cf );
698c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() );
699c2c66affSColin Finck SetLastError( 0xdeadbeef );
700c2c66affSColin Finck cf = EnumClipboardFormats(cf);
701c2c66affSColin Finck ok( cf == CF_LOCALE, "cf %08x\n", cf );
702c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() );
703c2c66affSColin Finck SetLastError( 0xdeadbeef );
704c2c66affSColin Finck cf = EnumClipboardFormats( cf );
705c2c66affSColin Finck ok( cf == 0, "cf %08x\n", cf );
706c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() );
707c2c66affSColin Finck SetLastError( 0xdeadbeef );
708c2c66affSColin Finck cf = EnumClipboardFormats( 0xdead );
709c2c66affSColin Finck ok( cf == 0, "cf %08x\n", cf );
710c2c66affSColin Finck ok( GetLastError() == ERROR_SUCCESS, "wrong error %u\n", GetLastError() );
711c2c66affSColin Finck
712c2c66affSColin Finck r = EmptyClipboard();
713c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
714c2c66affSColin Finck
715c2c66affSColin Finck r = CloseClipboard();
716c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
717c2c66affSColin Finck
718*7a62c32bSAmine Khaldi for (i = 0; i < ARRAY_SIZE(tests); i++)
719c2c66affSColin Finck {
720c2c66affSColin Finck r = OpenClipboard(NULL);
721c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
722c2c66affSColin Finck r = EmptyClipboard();
723c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
724c2c66affSColin Finck
725c2c66affSColin Finck switch (tests[i].format)
726c2c66affSColin Finck {
727c2c66affSColin Finck case CF_TEXT:
728c2c66affSColin Finck case CF_OEMTEXT:
729c2c66affSColin Finck SetClipboardData( tests[i].format, create_textA() );
730c2c66affSColin Finck break;
731c2c66affSColin Finck case CF_UNICODETEXT:
732c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, create_textW() );
733c2c66affSColin Finck break;
734c2c66affSColin Finck case CF_ENHMETAFILE:
735c2c66affSColin Finck SetClipboardData( CF_ENHMETAFILE, create_emf() );
736c2c66affSColin Finck break;
737c2c66affSColin Finck case CF_METAFILEPICT:
738c2c66affSColin Finck SetClipboardData( CF_METAFILEPICT, create_metafile() );
739c2c66affSColin Finck break;
740c2c66affSColin Finck case CF_BITMAP:
741c2c66affSColin Finck SetClipboardData( CF_BITMAP, create_bitmap() );
742c2c66affSColin Finck break;
743c2c66affSColin Finck case CF_DIB:
744c2c66affSColin Finck case CF_DIBV5:
745c2c66affSColin Finck SetClipboardData( tests[i].format, create_dib( tests[i].format == CF_DIBV5 ));
746c2c66affSColin Finck break;
747c2c66affSColin Finck }
748c2c66affSColin Finck
749c2c66affSColin Finck count = CountClipboardFormats();
750c2c66affSColin Finck ok( count == 1, "%u: count %u\n", i, count );
751c2c66affSColin Finck
752c2c66affSColin Finck r = CloseClipboard();
753c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
754c2c66affSColin Finck
755c2c66affSColin Finck count = CountClipboardFormats();
756c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++)
757c2c66affSColin Finck {
758c2c66affSColin Finck r = IsClipboardFormatAvailable( tests[i].expected[j] );
759c2c66affSColin Finck ok( r, "%u: %04x not available\n", i, tests[i].expected[j] );
760c2c66affSColin Finck }
761c2c66affSColin Finck ok( count == j, "%u: count %u instead of %u\n", i, count, j );
762c2c66affSColin Finck
763c2c66affSColin Finck r = OpenClipboard( hwnd );
764c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
765c2c66affSColin Finck cf = 0;
766c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++)
767c2c66affSColin Finck {
768c2c66affSColin Finck cf = EnumClipboardFormats( cf );
769c2c66affSColin Finck ok(cf == tests[i].expected[j], "%u.%u: got %04x instead of %04x\n",
770c2c66affSColin Finck i, j, cf, tests[i].expected[j] );
771c2c66affSColin Finck if (cf != tests[i].expected[j]) break;
772c2c66affSColin Finck old_seq = GetClipboardSequenceNumber();
773c2c66affSColin Finck data = GetClipboardData( cf );
774c2c66affSColin Finck ok(data != NULL ||
775c2c66affSColin Finck broken( tests[i].format == CF_DIBV5 && cf == CF_DIB ), /* >= Vista */
776c2c66affSColin Finck "%u: couldn't get data, cf %04x err %d\n", i, cf, GetLastError());
777c2c66affSColin Finck seq = GetClipboardSequenceNumber();
778c2c66affSColin Finck ok(seq == old_seq, "sequence changed (test %d %d)\n", i, cf);
779c2c66affSColin Finck switch (cf)
780c2c66affSColin Finck {
781c2c66affSColin Finck case CF_LOCALE:
782c2c66affSColin Finck {
783c2c66affSColin Finck UINT *ptr = GlobalLock( data );
784c2c66affSColin Finck ok( GlobalSize( data ) == sizeof(*ptr), "%u: size %lu\n", i, GlobalSize( data ));
785c2c66affSColin Finck ok( *ptr == GetUserDefaultLCID() ||
786c2c66affSColin Finck broken( *ptr == MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT )),
787c2c66affSColin Finck "%u: CF_LOCALE %08x/%08x\n", i, *ptr, GetUserDefaultLCID() );
788c2c66affSColin Finck GlobalUnlock( data );
789c2c66affSColin Finck break;
790c2c66affSColin Finck }
791c2c66affSColin Finck case CF_TEXT:
792c2c66affSColin Finck case CF_OEMTEXT:
793c2c66affSColin Finck ok( GlobalSize( data ) == 10, "wrong len %ld\n", GlobalSize( data ));
794c2c66affSColin Finck break;
795c2c66affSColin Finck case CF_UNICODETEXT:
796c2c66affSColin Finck ok( GlobalSize( data ) == 10 * sizeof(WCHAR), "wrong len %ld\n", GlobalSize( data ));
797c2c66affSColin Finck break;
798c2c66affSColin Finck }
799c2c66affSColin Finck }
800c2c66affSColin Finck if (!tests[i].expected[j])
801c2c66affSColin Finck {
802c2c66affSColin Finck cf = EnumClipboardFormats( cf );
803c2c66affSColin Finck ok(cf == 0, "%u: cf %04x\n", i, cf);
804c2c66affSColin Finck }
805c2c66affSColin Finck
806c2c66affSColin Finck /* now with delayed rendering */
807c2c66affSColin Finck
808c2c66affSColin Finck r = EmptyClipboard();
809c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
810c2c66affSColin Finck
811c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
812c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered );
813c2c66affSColin Finck
814c2c66affSColin Finck SetClipboardData( tests[i].format, 0 );
815c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
816c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered );
817c2c66affSColin Finck
818c2c66affSColin Finck count = CountClipboardFormats();
819c2c66affSColin Finck ok( count == 1, "%u: count %u\n", i, count );
820c2c66affSColin Finck
821c2c66affSColin Finck r = CloseClipboard();
822c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
823c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
824c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered );
825c2c66affSColin Finck
826c2c66affSColin Finck count = CountClipboardFormats();
827c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++)
828c2c66affSColin Finck {
829c2c66affSColin Finck r = IsClipboardFormatAvailable( tests[i].expected[j] );
830c2c66affSColin Finck ok( r, "%u: %04x not available\n", i, tests[i].expected[j] );
831c2c66affSColin Finck }
832c2c66affSColin Finck ok( count == j, "%u: count %u instead of %u\n", i, count, j );
833c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
834c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered );
835c2c66affSColin Finck
836c2c66affSColin Finck r = OpenClipboard(NULL);
837c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
838c2c66affSColin Finck cf = 0;
839c2c66affSColin Finck for (j = 0; tests[i].expected[j]; j++)
840c2c66affSColin Finck {
841c2c66affSColin Finck cf = EnumClipboardFormats( cf );
842c2c66affSColin Finck ok(cf == tests[i].expected[j], "%u.%u: got %04x instead of %04x\n",
843c2c66affSColin Finck i, j, cf, tests[i].expected[j] );
844c2c66affSColin Finck if (cf != tests[i].expected[j]) break;
845c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
846c2c66affSColin Finck ok( !rendered, "%u.%u: formats %08x have been rendered\n", i, j, rendered );
847c2c66affSColin Finck data = GetClipboardData( cf );
848c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
849c2c66affSColin Finck if (cf == CF_LOCALE)
850c2c66affSColin Finck {
851c2c66affSColin Finck ok(data != NULL, "%u: CF_LOCALE no data\n", i);
852c2c66affSColin Finck ok( !rendered, "%u.%u: formats %08x have been rendered\n", i, j, rendered );
853c2c66affSColin Finck }
854c2c66affSColin Finck else
855c2c66affSColin Finck {
856c2c66affSColin Finck ok(!data, "%u: format %04x got data %p\n", i, cf, data);
857c2c66affSColin Finck ok( rendered == (1 << tests[i].format),
858c2c66affSColin Finck "%u.%u: formats %08x have been rendered\n", i, j, rendered );
859c2c66affSColin Finck /* try to render a second time */
860c2c66affSColin Finck data = GetClipboardData( cf );
861c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
862c2c66affSColin Finck ok( rendered == (1 << tests[i].format),
863c2c66affSColin Finck "%u.%u: formats %08x have been rendered\n", i, j, rendered );
864c2c66affSColin Finck }
865c2c66affSColin Finck }
866c2c66affSColin Finck if (!tests[i].expected[j])
867c2c66affSColin Finck {
868c2c66affSColin Finck cf = EnumClipboardFormats( cf );
869c2c66affSColin Finck ok(cf == 0, "%u: cf %04x\n", i, cf);
870c2c66affSColin Finck }
871c2c66affSColin Finck r = CloseClipboard();
872c2c66affSColin Finck ok(r, "%u: gle %d\n", i, GetLastError());
873c2c66affSColin Finck rendered = SendMessageA( hwnd, WM_USER, 0, 0 );
874c2c66affSColin Finck ok( !rendered, "%u: formats %08x have been rendered\n", i, rendered );
875c2c66affSColin Finck }
876c2c66affSColin Finck
877c2c66affSColin Finck r = OpenClipboard(NULL);
878c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
879c2c66affSColin Finck r = EmptyClipboard();
880c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
881c2c66affSColin Finck r = CloseClipboard();
882c2c66affSColin Finck ok(r, "gle %d\n", GetLastError());
883c2c66affSColin Finck DestroyWindow( hwnd );
884c2c66affSColin Finck }
885c2c66affSColin Finck
clipboard_render_data_thread(void * param)886c2c66affSColin Finck static DWORD WINAPI clipboard_render_data_thread(void *param)
887c2c66affSColin Finck {
888c2c66affSColin Finck HANDLE handle = SetClipboardData( CF_UNICODETEXT, create_textW() );
889c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed: %d\n", GetLastError() );
890c2c66affSColin Finck return 0;
891c2c66affSColin Finck }
892c2c66affSColin Finck
893c2c66affSColin Finck static CRITICAL_SECTION clipboard_cs;
894c2c66affSColin Finck static HWND next_wnd;
895c2c66affSColin Finck static UINT wm_drawclipboard;
896c2c66affSColin Finck static UINT wm_clipboardupdate;
897c2c66affSColin Finck static UINT wm_destroyclipboard;
898c2c66affSColin Finck static UINT wm_renderformat;
899c2c66affSColin Finck static UINT nb_formats;
900c2c66affSColin Finck static BOOL cross_thread;
901c2c66affSColin Finck static BOOL do_render_format;
902d558fc75SAmine Khaldi static HANDLE update_event;
903c2c66affSColin Finck
clipboard_wnd_proc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)904c2c66affSColin Finck static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
905c2c66affSColin Finck {
906c2c66affSColin Finck LRESULT ret;
907c2c66affSColin Finck DWORD msg_flags = InSendMessageEx( NULL );
908c2c66affSColin Finck
909c2c66affSColin Finck switch(msg) {
910c2c66affSColin Finck case WM_DRAWCLIPBOARD:
911c2c66affSColin Finck ok( msg_flags == (cross_thread ? ISMEX_NOTIFY : ISMEX_NOSEND),
912c2c66affSColin Finck "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags );
913c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
914c2c66affSColin Finck wm_drawclipboard++;
915c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
916c2c66affSColin Finck break;
917c2c66affSColin Finck case WM_CHANGECBCHAIN:
918c2c66affSColin Finck ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND),
919c2c66affSColin Finck "WM_CHANGECBCHAIN wrong flags %x\n", msg_flags );
920c2c66affSColin Finck if (next_wnd == (HWND)wp)
921c2c66affSColin Finck next_wnd = (HWND)lp;
922c2c66affSColin Finck else if (next_wnd)
923c2c66affSColin Finck SendMessageA(next_wnd, msg, wp, lp);
924c2c66affSColin Finck break;
925c2c66affSColin Finck case WM_DESTROYCLIPBOARD:
926c2c66affSColin Finck ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND),
927c2c66affSColin Finck "WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags );
928c2c66affSColin Finck wm_destroyclipboard++;
929c2c66affSColin Finck ok( GetClipboardOwner() == hwnd, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
930c2c66affSColin Finck nb_formats = CountClipboardFormats();
931c2c66affSColin Finck break;
932c2c66affSColin Finck case WM_RENDERFORMAT:
933c2c66affSColin Finck ok( !wm_renderformat, "multiple WM_RENDERFORMAT %04x / %04lx\n", wm_renderformat, wp );
934c2c66affSColin Finck wm_renderformat = wp;
935c2c66affSColin Finck
936c2c66affSColin Finck if (do_render_format)
937c2c66affSColin Finck {
938c2c66affSColin Finck UINT seq, old_seq;
939c2c66affSColin Finck HANDLE handle;
940c2c66affSColin Finck
941c2c66affSColin Finck old_seq = GetClipboardSequenceNumber();
942c2c66affSColin Finck handle = SetClipboardData( CF_TEXT, create_textA() );
943c2c66affSColin Finck ok( handle != 0, "SetClipboardData failed: %d\n", GetLastError() );
944c2c66affSColin Finck seq = GetClipboardSequenceNumber();
945c2c66affSColin Finck ok( seq == old_seq, "sequence changed\n" );
946c2c66affSColin Finck old_seq = seq;
947c2c66affSColin Finck
948c2c66affSColin Finck handle = CreateThread( NULL, 0, clipboard_render_data_thread, NULL, 0, NULL );
949c2c66affSColin Finck ok( handle != NULL, "CreateThread failed: %d\n", GetLastError() );
950c2c66affSColin Finck ok( WaitForSingleObject(handle, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n" );
951c2c66affSColin Finck CloseHandle( handle );
952c2c66affSColin Finck seq = GetClipboardSequenceNumber();
953c2c66affSColin Finck ok( seq == old_seq, "sequence changed\n" );
954c2c66affSColin Finck }
955c2c66affSColin Finck
956c2c66affSColin Finck break;
957c2c66affSColin Finck case WM_CLIPBOARDUPDATE:
958c2c66affSColin Finck ok( msg_flags == ISMEX_NOSEND, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags );
959c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
960c2c66affSColin Finck wm_clipboardupdate++;
961d558fc75SAmine Khaldi SetEvent(update_event);
962c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
963c2c66affSColin Finck break;
964c2c66affSColin Finck case WM_USER:
965c2c66affSColin Finck ChangeClipboardChain(hwnd, next_wnd);
966c2c66affSColin Finck PostQuitMessage(0);
967c2c66affSColin Finck break;
968c2c66affSColin Finck case WM_USER+1:
969c2c66affSColin Finck ret = wm_drawclipboard;
970c2c66affSColin Finck wm_drawclipboard = 0;
971c2c66affSColin Finck return ret;
972c2c66affSColin Finck case WM_USER+2:
973c2c66affSColin Finck ret = wm_clipboardupdate;
974c2c66affSColin Finck wm_clipboardupdate = 0;
975c2c66affSColin Finck return ret;
976c2c66affSColin Finck case WM_USER+3:
977c2c66affSColin Finck ret = wm_destroyclipboard;
978c2c66affSColin Finck wm_destroyclipboard = 0;
979c2c66affSColin Finck return ret;
980c2c66affSColin Finck case WM_USER+4:
981c2c66affSColin Finck ret = wm_renderformat;
982c2c66affSColin Finck wm_renderformat = 0;
983c2c66affSColin Finck return ret;
984c2c66affSColin Finck case WM_USER+5:
985c2c66affSColin Finck return nb_formats;
986c2c66affSColin Finck }
987c2c66affSColin Finck
988c2c66affSColin Finck return DefWindowProcA(hwnd, msg, wp, lp);
989c2c66affSColin Finck }
990c2c66affSColin Finck
get_clipboard_data_process(void)991c2c66affSColin Finck static void get_clipboard_data_process(void)
992c2c66affSColin Finck {
993c2c66affSColin Finck HANDLE data;
994c2c66affSColin Finck BOOL r;
995c2c66affSColin Finck
996c2c66affSColin Finck r = OpenClipboard(0);
997c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
998c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT );
999c2c66affSColin Finck ok( data != NULL, "GetClipboardData failed: %d\n", GetLastError());
1000c2c66affSColin Finck r = CloseClipboard();
1001c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1002c2c66affSColin Finck }
1003c2c66affSColin Finck
1004d558fc75SAmine Khaldi static UINT old_seq;
1005d558fc75SAmine Khaldi
check_messages_(int line,HWND win,UINT seq_diff,UINT draw,UINT update,UINT destroy,UINT render)1006d558fc75SAmine Khaldi static void check_messages_(int line, HWND win, UINT seq_diff, UINT draw, UINT update, UINT destroy, UINT render)
1007d558fc75SAmine Khaldi {
1008d558fc75SAmine Khaldi MSG msg;
1009d558fc75SAmine Khaldi UINT count, fmt, seq;
1010d558fc75SAmine Khaldi
1011d558fc75SAmine Khaldi seq = GetClipboardSequenceNumber();
1012d558fc75SAmine Khaldi ok_(__FILE__, line)(seq - old_seq == seq_diff, "sequence diff %d\n", seq - old_seq);
1013d558fc75SAmine Khaldi old_seq = seq;
1014d558fc75SAmine Khaldi
1015d558fc75SAmine Khaldi if (!cross_thread)
1016d558fc75SAmine Khaldi {
1017d558fc75SAmine Khaldi while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
1018d558fc75SAmine Khaldi }
1019d558fc75SAmine Khaldi
1020d558fc75SAmine Khaldi if (update && !broken(!pAddClipboardFormatListener))
1021d558fc75SAmine Khaldi ok(WaitForSingleObject(update_event, 1000) == WAIT_OBJECT_0, "wait failed\n");
1022d558fc75SAmine Khaldi
1023d558fc75SAmine Khaldi count = SendMessageA( win, WM_USER + 1, 0, 0 );
1024d558fc75SAmine Khaldi ok_(__FILE__, line)(count == draw, "WM_DRAWCLIPBOARD %sreceived\n", draw ? "not " : "");
1025d558fc75SAmine Khaldi count = SendMessageA( win, WM_USER + 2, 0, 0 );
1026d558fc75SAmine Khaldi ok_(__FILE__, line)(count == update || broken(!pAddClipboardFormatListener),
1027d558fc75SAmine Khaldi "WM_CLIPBOARDUPDATE %sreceived\n", update ? "not " : "");
1028d558fc75SAmine Khaldi count = SendMessageA( win, WM_USER + 3, 0, 0 );
1029d558fc75SAmine Khaldi ok_(__FILE__, line)(count == destroy, "WM_DESTROYCLIPBOARD %sreceived\n", destroy ? "not " : "");
1030d558fc75SAmine Khaldi fmt = SendMessageA( win, WM_USER + 4, 0, 0 );
1031d558fc75SAmine Khaldi ok_(__FILE__, line)(fmt == render, "WM_RENDERFORMAT received %04x, expected %04x\n", fmt, render);
1032d558fc75SAmine Khaldi }
1033d558fc75SAmine Khaldi #define check_messages(a,b,c,d,e,f) check_messages_(__LINE__,a,b,c,d,e,f)
1034d558fc75SAmine Khaldi
clipboard_thread(void * param)1035c2c66affSColin Finck static DWORD WINAPI clipboard_thread(void *param)
1036c2c66affSColin Finck {
1037c2c66affSColin Finck HWND ret, win = param;
1038c2c66affSColin Finck BOOL r;
1039c2c66affSColin Finck MSG msg;
1040c2c66affSColin Finck HANDLE handle;
1041d558fc75SAmine Khaldi UINT count, fmt, formats;
1042c2c66affSColin Finck
1043c2c66affSColin Finck cross_thread = (GetWindowThreadProcessId( win, NULL ) != GetCurrentThreadId());
1044c2c66affSColin Finck trace( "%s-threaded test\n", cross_thread ? "multi" : "single" );
1045c2c66affSColin Finck
1046c2c66affSColin Finck old_seq = GetClipboardSequenceNumber();
1047c2c66affSColin Finck
1048c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
1049c2c66affSColin Finck SetLastError(0xdeadbeef);
1050c2c66affSColin Finck next_wnd = SetClipboardViewer(win);
1051c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
1052c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
1053c2c66affSColin Finck
1054c2c66affSColin Finck SetLastError( 0xdeadbeef );
1055c2c66affSColin Finck ret = SetClipboardViewer( (HWND)0xdead );
1056c2c66affSColin Finck ok( !ret, "SetClipboardViewer succeeded\n" );
1057c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
1058c2c66affSColin Finck SetLastError( 0xdeadbeef );
1059c2c66affSColin Finck r = ChangeClipboardChain( win, (HWND)0xdead );
1060c2c66affSColin Finck ok( !r, "ChangeClipboardChain succeeded\n" );
1061c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
1062c2c66affSColin Finck SetLastError( 0xdeadbeef );
1063c2c66affSColin Finck r = ChangeClipboardChain( (HWND)0xdead, next_wnd );
1064c2c66affSColin Finck ok( !r, "ChangeClipboardChain succeeded\n" );
1065c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
1066c2c66affSColin Finck
1067c2c66affSColin Finck if (pAddClipboardFormatListener)
1068c2c66affSColin Finck {
1069c2c66affSColin Finck r = pAddClipboardFormatListener(win);
1070c2c66affSColin Finck ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError());
1071c2c66affSColin Finck SetLastError( 0xdeadbeef );
1072c2c66affSColin Finck r = pAddClipboardFormatListener( win );
1073c2c66affSColin Finck ok( !r, "AddClipboardFormatListener succeeded\n" );
1074c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1075c2c66affSColin Finck SetLastError( 0xdeadbeef );
1076c2c66affSColin Finck r = pAddClipboardFormatListener( (HWND)0xdead );
1077c2c66affSColin Finck ok( !r, "AddClipboardFormatListener succeeded\n" );
1078c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
1079c2c66affSColin Finck r = pAddClipboardFormatListener( GetDesktopWindow() );
1080c2c66affSColin Finck ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError());
1081c2c66affSColin Finck r = pRemoveClipboardFormatListener( GetDesktopWindow() );
1082c2c66affSColin Finck ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1083c2c66affSColin Finck }
1084c2c66affSColin Finck
1085d558fc75SAmine Khaldi check_messages(win, 0, 1, 0, 0, 0);
1086c2c66affSColin Finck
1087c2c66affSColin Finck SetLastError( 0xdeadbeef );
1088c2c66affSColin Finck r = OpenClipboard( (HWND)0xdead );
1089c2c66affSColin Finck ok( !r, "OpenClipboard succeeded\n" );
1090c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
1091c2c66affSColin Finck
1092c2c66affSColin Finck r = OpenClipboard(win);
1093c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1094c2c66affSColin Finck
1095d558fc75SAmine Khaldi check_messages(win, 0, 0, 0, 0, 0);
1096c2c66affSColin Finck
1097c2c66affSColin Finck r = EmptyClipboard();
1098c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError());
1099c2c66affSColin Finck
1100d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1101c2c66affSColin Finck
1102c2c66affSColin Finck r = EmptyClipboard();
1103c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError());
1104c2c66affSColin Finck /* sequence changes again, even though it was already empty */
1105d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 1, 0);
1106c2c66affSColin Finck count = SendMessageA( win, WM_USER+5, 0, 0 );
1107c2c66affSColin Finck ok( !count, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count );
1108c2c66affSColin Finck
1109c2c66affSColin Finck handle = SetClipboardData( CF_TEXT, create_textA() );
1110c2c66affSColin Finck ok(handle != 0, "SetClipboardData failed: %d\n", GetLastError());
1111c2c66affSColin Finck
1112d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1113c2c66affSColin Finck
1114c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, 0 );
1115c2c66affSColin Finck
1116d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1117c2c66affSColin Finck
1118c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, 0 ); /* same data again */
1119c2c66affSColin Finck
1120d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1121c2c66affSColin Finck
1122c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" );
1123c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" );
1124c2c66affSColin Finck ok( !IsClipboardFormatAvailable( CF_OEMTEXT ), "CF_OEMTEXT available\n" );
1125c2c66affSColin Finck
1126c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
1127c2c66affSColin Finck r = CloseClipboard();
1128c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1129c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
1130c2c66affSColin Finck
1131d558fc75SAmine Khaldi check_messages(win, 2, 1, 1, 0, 0);
1132c2c66affSColin Finck
1133c2c66affSColin Finck r = OpenClipboard(win);
1134c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1135c2c66affSColin Finck
1136d558fc75SAmine Khaldi check_messages(win, 0, 0, 0, 0, 0);
1137c2c66affSColin Finck
1138c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" );
1139c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" );
1140c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_OEMTEXT ), "CF_OEMTEXT available\n" );
1141c2c66affSColin Finck
1142c2c66affSColin Finck ok( GetClipboardOwner() == win, "wrong owner %p\n", GetClipboardOwner());
1143c2c66affSColin Finck handle = GetClipboardData( CF_UNICODETEXT );
1144c2c66affSColin Finck ok( !handle, "got data for CF_UNICODETEXT\n" );
1145c2c66affSColin Finck fmt = SendMessageA( win, WM_USER+4, 0, 0 );
1146c2c66affSColin Finck ok( fmt == CF_UNICODETEXT, "WM_RENDERFORMAT received %04x\n", fmt );
1147c2c66affSColin Finck
1148c2c66affSColin Finck do_render_format = TRUE;
1149c2c66affSColin Finck handle = GetClipboardData( CF_OEMTEXT );
1150c2c66affSColin Finck ok( handle != NULL, "didn't get data for CF_OEMTEXT\n" );
1151c2c66affSColin Finck fmt = SendMessageA( win, WM_USER+4, 0, 0 );
1152c2c66affSColin Finck ok( fmt == CF_UNICODETEXT, "WM_RENDERFORMAT received %04x\n", fmt );
1153c2c66affSColin Finck do_render_format = FALSE;
1154c2c66affSColin Finck
1155c2c66affSColin Finck SetClipboardData( CF_WAVE, 0 );
1156d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1157c2c66affSColin Finck
1158c2c66affSColin Finck r = CloseClipboard();
1159c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1160c2c66affSColin Finck /* no synthesized format, so CloseClipboard doesn't change the sequence */
1161d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0);
1162c2c66affSColin Finck
1163c2c66affSColin Finck r = OpenClipboard(win);
1164c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1165c2c66affSColin Finck r = CloseClipboard();
1166c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1167c2c66affSColin Finck /* nothing changed */
1168d558fc75SAmine Khaldi check_messages(win, 0, 0, 0, 0, 0);
1169c2c66affSColin Finck
1170c2c66affSColin Finck formats = CountClipboardFormats();
1171c2c66affSColin Finck r = OpenClipboard(0);
1172c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1173c2c66affSColin Finck r = EmptyClipboard();
1174c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError());
1175c2c66affSColin Finck r = CloseClipboard();
1176c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1177c2c66affSColin Finck
1178d558fc75SAmine Khaldi check_messages(win, 1, 1, 1, 1, 0);
1179c2c66affSColin Finck count = SendMessageA( win, WM_USER+5, 0, 0 );
1180c2c66affSColin Finck ok( count == formats, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count );
1181c2c66affSColin Finck
1182c2c66affSColin Finck r = OpenClipboard(win);
1183c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1184c2c66affSColin Finck SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 ));
1185d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1186c2c66affSColin Finck
1187c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
1188c2c66affSColin Finck r = CloseClipboard();
1189c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1190c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
1191c2c66affSColin Finck
1192d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0);
1193c2c66affSColin Finck
1194c2c66affSColin Finck run_process( "grab_clipboard 0" );
1195c2c66affSColin Finck
1196c2c66affSColin Finck if (!cross_thread)
1197c2c66affSColin Finck {
1198c2c66affSColin Finck /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1199c2c66affSColin Finck cross_thread = TRUE;
1200c2c66affSColin Finck while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
1201c2c66affSColin Finck cross_thread = FALSE;
1202c2c66affSColin Finck }
1203d558fc75SAmine Khaldi check_messages(win, 1, 1, 1, 0, 0);
1204c2c66affSColin Finck
1205c2c66affSColin Finck r = OpenClipboard(0);
1206c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1207c2c66affSColin Finck SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 ));
1208d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1209c2c66affSColin Finck
1210c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
1211c2c66affSColin Finck r = CloseClipboard();
1212c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1213c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
1214c2c66affSColin Finck
1215d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0);
1216c2c66affSColin Finck
1217c2c66affSColin Finck run_process( "grab_clipboard 1" );
1218c2c66affSColin Finck
1219c2c66affSColin Finck if (!cross_thread)
1220c2c66affSColin Finck {
1221c2c66affSColin Finck /* in this case we get a cross-thread WM_DRAWCLIPBOARD */
1222c2c66affSColin Finck cross_thread = TRUE;
1223c2c66affSColin Finck while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
1224c2c66affSColin Finck cross_thread = FALSE;
1225c2c66affSColin Finck }
1226d558fc75SAmine Khaldi check_messages(win, 2, 1, 1, 0, 0);
1227c2c66affSColin Finck
1228c2c66affSColin Finck r = OpenClipboard(0);
1229c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1230c2c66affSColin Finck SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 ));
1231d558fc75SAmine Khaldi check_messages(win, 1, 0, 0, 0, 0);
1232c2c66affSColin Finck
1233c2c66affSColin Finck EnterCriticalSection(&clipboard_cs);
1234c2c66affSColin Finck r = CloseClipboard();
1235c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1236c2c66affSColin Finck LeaveCriticalSection(&clipboard_cs);
1237c2c66affSColin Finck
1238d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, 0);
1239c2c66affSColin Finck
1240c2c66affSColin Finck if (cross_thread)
1241c2c66affSColin Finck {
1242c2c66affSColin Finck r = OpenClipboard( win );
1243c2c66affSColin Finck ok(r, "OpenClipboard failed: %d\n", GetLastError());
1244c2c66affSColin Finck r = EmptyClipboard();
1245c2c66affSColin Finck ok(r, "EmptyClipboard failed: %d\n", GetLastError());
1246c2c66affSColin Finck SetClipboardData( CF_TEXT, 0 );
1247c2c66affSColin Finck r = CloseClipboard();
1248c2c66affSColin Finck ok(r, "CloseClipboard failed: %d\n", GetLastError());
1249c2c66affSColin Finck
1250c2c66affSColin Finck do_render_format = TRUE;
1251c2c66affSColin Finck old_seq = GetClipboardSequenceNumber();
1252c2c66affSColin Finck run_process( "get_clipboard_data" );
1253c2c66affSColin Finck do_render_format = FALSE;
1254c2c66affSColin Finck
1255d558fc75SAmine Khaldi check_messages(win, 0, 1, 1, 0, CF_TEXT);
1256c2c66affSColin Finck }
1257c2c66affSColin Finck
1258c2c66affSColin Finck r = PostMessageA(win, WM_USER, 0, 0);
1259c2c66affSColin Finck ok(r, "PostMessage failed: %d\n", GetLastError());
1260c2c66affSColin Finck
1261c2c66affSColin Finck if (pRemoveClipboardFormatListener)
1262c2c66affSColin Finck {
1263c2c66affSColin Finck r = pRemoveClipboardFormatListener(win);
1264c2c66affSColin Finck ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
1265c2c66affSColin Finck SetLastError( 0xdeadbeef );
1266c2c66affSColin Finck r = pRemoveClipboardFormatListener(win);
1267c2c66affSColin Finck ok( !r, "RemoveClipboardFormatListener succeeded\n" );
1268c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1269c2c66affSColin Finck SetLastError( 0xdeadbeef );
1270c2c66affSColin Finck r = pRemoveClipboardFormatListener( (HWND)0xdead );
1271c2c66affSColin Finck ok( !r, "RemoveClipboardFormatListener succeeded\n" );
1272c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
1273c2c66affSColin Finck }
1274c2c66affSColin Finck return 0;
1275c2c66affSColin Finck }
1276c2c66affSColin Finck
test_messages(void)1277c2c66affSColin Finck static void test_messages(void)
1278c2c66affSColin Finck {
1279c2c66affSColin Finck WNDCLASSA cls;
1280c2c66affSColin Finck HWND win;
1281c2c66affSColin Finck MSG msg;
1282c2c66affSColin Finck HANDLE thread;
1283c2c66affSColin Finck DWORD tid;
1284c2c66affSColin Finck
1285c2c66affSColin Finck InitializeCriticalSection(&clipboard_cs);
1286d558fc75SAmine Khaldi update_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1287c2c66affSColin Finck
1288c2c66affSColin Finck memset(&cls, 0, sizeof(cls));
1289c2c66affSColin Finck cls.lpfnWndProc = clipboard_wnd_proc;
1290c2c66affSColin Finck cls.hInstance = GetModuleHandleA(NULL);
1291c2c66affSColin Finck cls.lpszClassName = "clipboard_test";
1292c2c66affSColin Finck RegisterClassA(&cls);
1293c2c66affSColin Finck
1294c2c66affSColin Finck win = CreateWindowA("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0);
1295c2c66affSColin Finck ok(win != NULL, "CreateWindow failed: %d\n", GetLastError());
1296c2c66affSColin Finck
1297c2c66affSColin Finck thread = CreateThread(NULL, 0, clipboard_thread, (void*)win, 0, &tid);
1298c2c66affSColin Finck ok(thread != NULL, "CreateThread failed: %d\n", GetLastError());
1299c2c66affSColin Finck
1300c2c66affSColin Finck while(GetMessageA(&msg, NULL, 0, 0))
1301c2c66affSColin Finck {
1302c2c66affSColin Finck ok( msg.message != WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD was posted\n" );
1303c2c66affSColin Finck TranslateMessage(&msg);
1304c2c66affSColin Finck DispatchMessageA(&msg);
1305c2c66affSColin Finck }
1306c2c66affSColin Finck
1307c2c66affSColin Finck ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1308c2c66affSColin Finck CloseHandle(thread);
1309c2c66affSColin Finck
1310c2c66affSColin Finck DestroyWindow( win );
1311c2c66affSColin Finck
1312c2c66affSColin Finck /* same tests again but inside a single thread */
1313c2c66affSColin Finck
1314c2c66affSColin Finck win = CreateWindowA( "clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0 );
1315c2c66affSColin Finck ok( win != NULL, "CreateWindow failed: %d\n", GetLastError() );
1316c2c66affSColin Finck
1317c2c66affSColin Finck clipboard_thread( win );
1318c2c66affSColin Finck DestroyWindow( win );
1319c2c66affSColin Finck
1320c2c66affSColin Finck UnregisterClassA("clipboard_test", GetModuleHandleA(NULL));
1321c2c66affSColin Finck DeleteCriticalSection(&clipboard_cs);
1322c2c66affSColin Finck }
1323c2c66affSColin Finck
is_moveable(HANDLE handle)1324c2c66affSColin Finck static BOOL is_moveable( HANDLE handle )
1325c2c66affSColin Finck {
1326c2c66affSColin Finck void *ptr = GlobalLock( handle );
1327c2c66affSColin Finck if (ptr) GlobalUnlock( handle );
1328c2c66affSColin Finck return ptr && ptr != handle;
1329c2c66affSColin Finck }
1330c2c66affSColin Finck
is_fixed(HANDLE handle)1331c2c66affSColin Finck static BOOL is_fixed( HANDLE handle )
1332c2c66affSColin Finck {
1333c2c66affSColin Finck void *ptr = GlobalLock( handle );
1334c2c66affSColin Finck if (ptr) GlobalUnlock( handle );
1335c2c66affSColin Finck return ptr && ptr == handle;
1336c2c66affSColin Finck }
1337c2c66affSColin Finck
is_freed(HANDLE handle)1338c2c66affSColin Finck static BOOL is_freed( HANDLE handle )
1339c2c66affSColin Finck {
1340c2c66affSColin Finck return !GlobalSize( handle );
1341c2c66affSColin Finck }
1342c2c66affSColin Finck
1343c2c66affSColin Finck static UINT format_id;
1344c2c66affSColin Finck static HBITMAP bitmap, bitmap2;
1345c2c66affSColin Finck static HPALETTE palette;
1346c2c66affSColin Finck static const LOGPALETTE logpalette = { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}};
1347c2c66affSColin Finck
test_handles(HWND hwnd)1348c2c66affSColin Finck static void test_handles( HWND hwnd )
1349c2c66affSColin Finck {
1350c2c66affSColin Finck HGLOBAL h, htext, htext2, htext3, htext4, htext5;
1351c2c66affSColin Finck HGLOBAL hfixed, hfixed2, hmoveable, empty_fixed, empty_moveable;
1352c2c66affSColin Finck void *ptr;
1353c2c66affSColin Finck UINT format_id2 = RegisterClipboardFormatA( "another format" );
1354c2c66affSColin Finck BOOL r;
1355c2c66affSColin Finck HANDLE data;
1356c2c66affSColin Finck HBITMAP bitmap_temp;
1357c2c66affSColin Finck DWORD process;
1358c2c66affSColin Finck BOOL is_owner = (GetWindowThreadProcessId( hwnd, &process ) && process == GetCurrentProcessId());
1359c2c66affSColin Finck
1360c2c66affSColin Finck trace( "hwnd %p\n", hwnd );
1361c2c66affSColin Finck htext = create_textA();
1362c2c66affSColin Finck htext2 = create_textA();
1363c2c66affSColin Finck htext3 = create_textA();
1364c2c66affSColin Finck htext4 = create_textA();
1365c2c66affSColin Finck htext5 = create_textA();
1366c2c66affSColin Finck bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
1367c2c66affSColin Finck bitmap2 = CreateBitmap( 10, 10, 1, 1, NULL );
1368c2c66affSColin Finck palette = CreatePalette( &logpalette );
1369c2c66affSColin Finck
1370c2c66affSColin Finck hfixed = GlobalAlloc( GMEM_FIXED, 17 );
1371c2c66affSColin Finck hfixed2 = GlobalAlloc( GMEM_FIXED, 17 );
1372c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1373c2c66affSColin Finck ok( GlobalSize( hfixed ) == 17, "wrong size %lu\n", GlobalSize( hfixed ));
1374c2c66affSColin Finck
1375c2c66affSColin Finck hmoveable = GlobalAlloc( GMEM_MOVEABLE, 23 );
1376c2c66affSColin Finck ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable );
1377c2c66affSColin Finck ok( GlobalSize( hmoveable ) == 23, "wrong size %lu\n", GlobalSize( hmoveable ));
1378c2c66affSColin Finck
1379c2c66affSColin Finck empty_fixed = GlobalAlloc( GMEM_FIXED, 0 );
1380c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1381c2c66affSColin Finck
1382c2c66affSColin Finck empty_moveable = GlobalAlloc( GMEM_MOVEABLE, 0 );
1383c2c66affSColin Finck /* discarded handles can't be GlobalLock'ed */
1384c2c66affSColin Finck ok( is_freed( empty_moveable ), "expected free mem %p\n", empty_moveable );
1385c2c66affSColin Finck
1386c2c66affSColin Finck r = OpenClipboard( hwnd );
1387c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1388c2c66affSColin Finck r = EmptyClipboard();
1389c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1390c2c66affSColin Finck
1391c2c66affSColin Finck h = SetClipboardData( CF_TEXT, htext );
1392c2c66affSColin Finck ok( h == htext, "got %p\n", h );
1393c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1394c2c66affSColin Finck h = SetClipboardData( format_id, htext2 );
1395c2c66affSColin Finck ok( h == htext2, "got %p\n", h );
1396c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1397c2c66affSColin Finck bitmap_temp = CreateBitmap( 10, 10, 1, 1, NULL );
1398c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap_temp );
1399c2c66affSColin Finck ok( h == bitmap_temp, "got %p\n", h );
1400c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1401c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap );
1402c2c66affSColin Finck ok( h == bitmap, "got %p\n", h );
1403c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1404c2c66affSColin Finck ok( !GetObjectType( bitmap_temp ), "expected free object %p\n", bitmap_temp );
1405c2c66affSColin Finck h = SetClipboardData( CF_DSPBITMAP, bitmap2 );
1406c2c66affSColin Finck ok( h == bitmap2, "got %p\n", h );
1407c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1408c2c66affSColin Finck h = SetClipboardData( CF_PALETTE, palette );
1409c2c66affSColin Finck ok( h == palette, "got %p\n", h );
1410c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1411c2c66affSColin Finck h = SetClipboardData( CF_GDIOBJFIRST + 3, htext3 );
1412c2c66affSColin Finck ok( h == htext3, "got %p\n", h );
1413c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1414c2c66affSColin Finck h = SetClipboardData( CF_PRIVATEFIRST + 7, htext5 );
1415c2c66affSColin Finck ok( h == htext5, "got %p\n", h );
1416c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1417c2c66affSColin Finck h = SetClipboardData( format_id2, empty_moveable );
1418c2c66affSColin Finck ok( !h, "got %p\n", h );
1419c2c66affSColin Finck GlobalFree( empty_moveable );
1420c2c66affSColin Finck
1421c2c66affSColin Finck if (0) /* crashes on vista64 */
1422c2c66affSColin Finck {
1423c2c66affSColin Finck ptr = HeapAlloc( GetProcessHeap(), 0, 0 );
1424c2c66affSColin Finck h = SetClipboardData( format_id2, ptr );
1425c2c66affSColin Finck ok( !h, "got %p\n", h );
1426c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, ptr );
1427c2c66affSColin Finck }
1428c2c66affSColin Finck
1429c2c66affSColin Finck h = SetClipboardData( format_id2, empty_fixed );
1430c2c66affSColin Finck ok( h == empty_fixed, "got %p\n", h );
1431c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1432c2c66affSColin Finck h = SetClipboardData( 0xdeadbeef, hfixed2 );
1433c2c66affSColin Finck ok( h == hfixed2, "got %p\n", h );
1434c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1435c2c66affSColin Finck h = SetClipboardData( 0xdeadbabe, hmoveable );
1436c2c66affSColin Finck ok( h == hmoveable, "got %p\n", h );
1437c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1438c2c66affSColin Finck
1439c2c66affSColin Finck ptr = HeapAlloc( GetProcessHeap(), 0, 37 );
1440c2c66affSColin Finck h = SetClipboardData( 0xdeadfade, ptr );
1441c2c66affSColin Finck ok( h == ptr || !h, "got %p\n", h );
1442c2c66affSColin Finck if (!h) /* heap blocks are rejected on >= win8 */
1443c2c66affSColin Finck {
1444c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, ptr );
1445c2c66affSColin Finck ptr = NULL;
1446c2c66affSColin Finck }
1447c2c66affSColin Finck
1448c2c66affSColin Finck data = GetClipboardData( CF_TEXT );
1449c2c66affSColin Finck ok( data == htext, "wrong data %p\n", data );
1450c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data );
1451c2c66affSColin Finck
1452c2c66affSColin Finck data = GetClipboardData( format_id );
1453c2c66affSColin Finck ok( data == htext2, "wrong data %p, cf %08x\n", data, format_id );
1454c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data );
1455c2c66affSColin Finck
1456c2c66affSColin Finck data = GetClipboardData( CF_GDIOBJFIRST + 3 );
1457c2c66affSColin Finck ok( data == htext3, "wrong data %p\n", data );
1458c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data );
1459c2c66affSColin Finck
1460c2c66affSColin Finck data = GetClipboardData( CF_PRIVATEFIRST + 7 );
1461c2c66affSColin Finck ok( data == htext5, "wrong data %p\n", data );
1462c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data );
1463c2c66affSColin Finck
1464c2c66affSColin Finck data = GetClipboardData( format_id2 );
1465c2c66affSColin Finck ok( data == empty_fixed, "wrong data %p\n", data );
1466c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1467c2c66affSColin Finck
1468c2c66affSColin Finck data = GetClipboardData( 0xdeadbeef );
1469c2c66affSColin Finck ok( data == hfixed2, "wrong data %p\n", data );
1470c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1471c2c66affSColin Finck
1472c2c66affSColin Finck data = GetClipboardData( 0xdeadbabe );
1473c2c66affSColin Finck ok( data == hmoveable, "wrong data %p\n", data );
1474c2c66affSColin Finck ok( is_moveable( data ), "expected moveable mem %p\n", data );
1475c2c66affSColin Finck
1476c2c66affSColin Finck data = GetClipboardData( 0xdeadfade );
1477c2c66affSColin Finck ok( data == ptr, "wrong data %p\n", data );
1478c2c66affSColin Finck
1479c2c66affSColin Finck h = SetClipboardData( CF_PRIVATEFIRST + 7, htext4 );
1480c2c66affSColin Finck ok( h == htext4, "got %p\n", h );
1481c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1482c2c66affSColin Finck ok( is_freed( htext5 ), "expected freed mem %p\n", htext5 );
1483c2c66affSColin Finck
1484c2c66affSColin Finck h = SetClipboardData( 0xdeadbeef, hfixed );
1485c2c66affSColin Finck ok( h == hfixed, "got %p\n", h );
1486c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1487d558fc75SAmine Khaldi if (0) /* this test is unreliable / crashes */
1488d558fc75SAmine Khaldi ok( is_freed( hfixed2 ), "expected freed mem %p\n", hfixed2 );
1489c2c66affSColin Finck
1490c2c66affSColin Finck r = CloseClipboard();
1491c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1492c2c66affSColin Finck
1493c2c66affSColin Finck /* data handles are still valid */
1494c2c66affSColin Finck ok( is_moveable( htext ), "expected moveable mem %p\n", htext );
1495c2c66affSColin Finck ok( is_moveable( htext2 ), "expected moveable mem %p\n", htext2 );
1496c2c66affSColin Finck ok( is_moveable( htext3 ), "expected moveable mem %p\n", htext3 );
1497c2c66affSColin Finck ok( is_moveable( htext4 ), "expected moveable mem %p\n", htext4 );
1498c2c66affSColin Finck ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap );
1499c2c66affSColin Finck ok( GetObjectType( bitmap2 ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap2 );
1500c2c66affSColin Finck ok( GetObjectType( palette ) == OBJ_PAL, "expected palette %p\n", palette );
1501c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1502c2c66affSColin Finck ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable );
1503c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1504c2c66affSColin Finck
1505c2c66affSColin Finck r = OpenClipboard( hwnd );
1506c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1507c2c66affSColin Finck
1508c2c66affSColin Finck /* and now they are freed, unless we are the owner */
1509c2c66affSColin Finck if (!is_owner)
1510c2c66affSColin Finck {
1511c2c66affSColin Finck ok( is_freed( htext ), "expected freed mem %p\n", htext );
1512c2c66affSColin Finck ok( is_freed( htext2 ), "expected freed mem %p\n", htext2 );
1513c2c66affSColin Finck ok( is_freed( htext3 ), "expected freed mem %p\n", htext3 );
1514c2c66affSColin Finck ok( is_freed( htext4 ), "expected freed mem %p\n", htext4 );
1515c2c66affSColin Finck ok( is_freed( hmoveable ), "expected freed mem %p\n", hmoveable );
1516c2c66affSColin Finck
1517c2c66affSColin Finck data = GetClipboardData( CF_TEXT );
1518c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1519c2c66affSColin Finck
1520c2c66affSColin Finck data = GetClipboardData( format_id );
1521c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1522c2c66affSColin Finck
1523c2c66affSColin Finck data = GetClipboardData( CF_GDIOBJFIRST + 3 );
1524c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1525c2c66affSColin Finck
1526c2c66affSColin Finck data = GetClipboardData( CF_PRIVATEFIRST + 7 );
1527c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1528c2c66affSColin Finck
1529c2c66affSColin Finck data = GetClipboardData( format_id2 );
1530c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1531c2c66affSColin Finck ok( GlobalSize( data ) == 1, "wrong size %lu\n", GlobalSize( data ));
1532c2c66affSColin Finck
1533c2c66affSColin Finck data = GetClipboardData( 0xdeadbeef );
1534c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1535c2c66affSColin Finck ok( GlobalSize( data ) == 17, "wrong size %lu\n", GlobalSize( data ));
1536c2c66affSColin Finck
1537c2c66affSColin Finck data = GetClipboardData( 0xdeadbabe );
1538c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1539c2c66affSColin Finck ok( GlobalSize( data ) == 23, "wrong size %lu\n", GlobalSize( data ));
1540c2c66affSColin Finck
1541c2c66affSColin Finck data = GetClipboardData( 0xdeadfade );
1542c2c66affSColin Finck ok( is_fixed( data ) || !ptr, "expected fixed mem %p\n", data );
1543c2c66affSColin Finck if (ptr) ok( GlobalSize( data ) == 37, "wrong size %lu\n", GlobalSize( data ));
1544c2c66affSColin Finck }
1545c2c66affSColin Finck else
1546c2c66affSColin Finck {
1547c2c66affSColin Finck ok( is_moveable( htext ), "expected moveable mem %p\n", htext );
1548c2c66affSColin Finck ok( is_moveable( htext2 ), "expected moveable mem %p\n", htext2 );
1549c2c66affSColin Finck ok( is_moveable( htext3 ), "expected moveable mem %p\n", htext3 );
1550c2c66affSColin Finck ok( is_moveable( htext4 ), "expected moveable mem %p\n", htext4 );
1551c2c66affSColin Finck ok( is_moveable( hmoveable ), "expected moveable mem %p\n", hmoveable );
1552c2c66affSColin Finck
1553c2c66affSColin Finck data = GetClipboardData( CF_TEXT );
1554c2c66affSColin Finck ok( data == htext, "wrong data %p\n", data );
1555c2c66affSColin Finck
1556c2c66affSColin Finck data = GetClipboardData( format_id );
1557c2c66affSColin Finck ok( data == htext2, "wrong data %p, cf %08x\n", data, format_id );
1558c2c66affSColin Finck
1559c2c66affSColin Finck data = GetClipboardData( CF_GDIOBJFIRST + 3 );
1560c2c66affSColin Finck ok( data == htext3, "wrong data %p\n", data );
1561c2c66affSColin Finck
1562c2c66affSColin Finck data = GetClipboardData( CF_PRIVATEFIRST + 7 );
1563c2c66affSColin Finck ok( data == htext4, "wrong data %p\n", data );
1564c2c66affSColin Finck
1565c2c66affSColin Finck data = GetClipboardData( format_id2 );
1566c2c66affSColin Finck ok( data == empty_fixed, "wrong data %p\n", data );
1567c2c66affSColin Finck
1568c2c66affSColin Finck data = GetClipboardData( 0xdeadbeef );
1569c2c66affSColin Finck ok( data == hfixed, "wrong data %p\n", data );
1570c2c66affSColin Finck
1571c2c66affSColin Finck data = GetClipboardData( 0xdeadbabe );
1572c2c66affSColin Finck ok( data == hmoveable, "wrong data %p\n", data );
1573c2c66affSColin Finck
1574c2c66affSColin Finck data = GetClipboardData( 0xdeadfade );
1575c2c66affSColin Finck ok( data == ptr, "wrong data %p\n", data );
1576c2c66affSColin Finck }
1577c2c66affSColin Finck
1578c2c66affSColin Finck data = GetClipboardData( CF_OEMTEXT );
1579c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1580c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT );
1581c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1582c2c66affSColin Finck data = GetClipboardData( CF_LOCALE );
1583c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1584c2c66affSColin Finck data = GetClipboardData( CF_BITMAP );
1585c2c66affSColin Finck ok( data == bitmap, "expected bitmap %p\n", data );
1586c2c66affSColin Finck data = GetClipboardData( CF_DSPBITMAP );
1587c2c66affSColin Finck ok( data == bitmap2, "expected bitmap %p\n", data );
1588c2c66affSColin Finck data = GetClipboardData( CF_PALETTE );
1589c2c66affSColin Finck ok( data == palette, "expected palette %p\n", data );
1590c2c66affSColin Finck data = GetClipboardData( CF_DIB );
1591c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1592c2c66affSColin Finck data = GetClipboardData( CF_DIBV5 );
1593c2c66affSColin Finck ok( is_fixed( data ), "expected fixed mem %p\n", data );
1594c2c66affSColin Finck
1595c2c66affSColin Finck ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap );
1596c2c66affSColin Finck ok( GetObjectType( bitmap2 ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap2 );
1597c2c66affSColin Finck ok( GetObjectType( palette ) == OBJ_PAL, "expected palette %p\n", palette );
1598c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1599c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1600c2c66affSColin Finck
1601c2c66affSColin Finck r = EmptyClipboard();
1602c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1603c2c66affSColin Finck
1604c2c66affSColin Finck /* w2003, w2008 don't seem to free the data here */
1605c2c66affSColin Finck ok( is_freed( htext ) || broken( !is_freed( htext )), "expected freed mem %p\n", htext );
1606c2c66affSColin Finck ok( is_freed( htext2 ) || broken( !is_freed( htext2 )), "expected freed mem %p\n", htext2 );
1607c2c66affSColin Finck ok( is_freed( htext3 ) || broken( !is_freed( htext3 )), "expected freed mem %p\n", htext3 );
1608c2c66affSColin Finck ok( is_freed( htext4 ) || broken( !is_freed( htext4 )), "expected freed mem %p\n", htext4 );
1609c2c66affSColin Finck ok( is_freed( hmoveable ) || broken( !is_freed( hmoveable )), "expected freed mem %p\n", hmoveable );
1610c2c66affSColin Finck ok( is_fixed( empty_fixed ), "expected fixed mem %p\n", empty_fixed );
1611c2c66affSColin Finck ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed );
1612c2c66affSColin Finck ok( !GetObjectType( bitmap ), "expected freed handle %p\n", bitmap );
1613c2c66affSColin Finck ok( !GetObjectType( bitmap2 ), "expected freed handle %p\n", bitmap2 );
1614c2c66affSColin Finck ok( !GetObjectType( palette ), "expected freed handle %p\n", palette );
1615c2c66affSColin Finck
1616c2c66affSColin Finck r = CloseClipboard();
1617c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1618c2c66affSColin Finck }
1619c2c66affSColin Finck
test_handles_thread(void * arg)1620c2c66affSColin Finck static DWORD WINAPI test_handles_thread( void *arg )
1621c2c66affSColin Finck {
1622c2c66affSColin Finck trace( "running from different thread\n" );
1623c2c66affSColin Finck test_handles( (HWND)arg );
1624c2c66affSColin Finck return 0;
1625c2c66affSColin Finck }
1626c2c66affSColin Finck
test_handles_thread2(void * arg)1627c2c66affSColin Finck static DWORD WINAPI test_handles_thread2( void *arg )
1628c2c66affSColin Finck {
1629c2c66affSColin Finck BOOL r;
1630c2c66affSColin Finck HANDLE h;
1631c2c66affSColin Finck char *ptr;
1632c2c66affSColin Finck
1633c2c66affSColin Finck r = OpenClipboard( 0 );
1634c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1635c2c66affSColin Finck h = GetClipboardData( CF_TEXT );
1636c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1637c2c66affSColin Finck ptr = GlobalLock( h );
1638c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1639c2c66affSColin Finck GlobalUnlock( h );
1640c2c66affSColin Finck h = GetClipboardData( format_id );
1641c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1642c2c66affSColin Finck ptr = GlobalLock( h );
1643c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1644c2c66affSColin Finck GlobalUnlock( h );
1645c2c66affSColin Finck h = GetClipboardData( CF_GDIOBJFIRST + 3 );
1646c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1647c2c66affSColin Finck ptr = GlobalLock( h );
1648c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1649c2c66affSColin Finck GlobalUnlock( h );
1650c2c66affSColin Finck trace( "gdiobj %p\n", h );
1651c2c66affSColin Finck h = GetClipboardData( CF_PRIVATEFIRST + 7 );
1652c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1653c2c66affSColin Finck ptr = GlobalLock( h );
1654c2c66affSColin Finck if (ptr) ok( !strcmp( "test", ptr ), "wrong data '%.5s'\n", ptr );
1655c2c66affSColin Finck GlobalUnlock( h );
1656c2c66affSColin Finck trace( "private %p\n", h );
1657c2c66affSColin Finck h = GetClipboardData( CF_BITMAP );
1658c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1659c2c66affSColin Finck ok( h == bitmap, "different bitmap %p / %p\n", h, bitmap );
1660c2c66affSColin Finck trace( "bitmap %p\n", h );
1661c2c66affSColin Finck h = GetClipboardData( CF_DSPBITMAP );
1662c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1663c2c66affSColin Finck ok( h == bitmap2, "different bitmap %p / %p\n", h, bitmap2 );
1664c2c66affSColin Finck trace( "bitmap2 %p\n", h );
1665c2c66affSColin Finck h = GetClipboardData( CF_PALETTE );
1666c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1667c2c66affSColin Finck ok( h == palette, "different palette %p / %p\n", h, palette );
1668c2c66affSColin Finck trace( "palette %p\n", h );
1669c2c66affSColin Finck h = GetClipboardData( CF_DIB );
1670c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1671c2c66affSColin Finck h = GetClipboardData( CF_DIBV5 );
1672c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1673c2c66affSColin Finck r = CloseClipboard();
1674c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1675c2c66affSColin Finck return 0;
1676c2c66affSColin Finck }
1677c2c66affSColin Finck
test_handles_process(const char * str)1678c2c66affSColin Finck static void test_handles_process( const char *str )
1679c2c66affSColin Finck {
1680c2c66affSColin Finck BOOL r;
1681c2c66affSColin Finck HANDLE h;
1682c2c66affSColin Finck char *ptr;
1683c2c66affSColin Finck BITMAP bm;
1684c2c66affSColin Finck PALETTEENTRY entry;
1685c2c66affSColin Finck BYTE buffer[1024];
1686c2c66affSColin Finck
1687c2c66affSColin Finck format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" );
1688c2c66affSColin Finck r = OpenClipboard( 0 );
1689c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1690c2c66affSColin Finck h = GetClipboardData( CF_TEXT );
1691c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1692c2c66affSColin Finck ptr = GlobalLock( h );
1693c2c66affSColin Finck ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1694c2c66affSColin Finck GlobalUnlock( h );
1695c2c66affSColin Finck h = GetClipboardData( format_id );
1696c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1697c2c66affSColin Finck ptr = GlobalLock( h );
1698c2c66affSColin Finck if (ptr) ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1699c2c66affSColin Finck GlobalUnlock( h );
1700c2c66affSColin Finck h = GetClipboardData( CF_GDIOBJFIRST + 3 );
1701c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1702c2c66affSColin Finck ptr = GlobalLock( h );
1703c2c66affSColin Finck ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1704c2c66affSColin Finck GlobalUnlock( h );
1705c2c66affSColin Finck trace( "gdiobj %p\n", h );
1706c2c66affSColin Finck h = GetClipboardData( CF_PRIVATEFIRST + 7 );
1707c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1708c2c66affSColin Finck ptr = GlobalLock( h );
1709c2c66affSColin Finck ok( !strcmp( str, ptr ), "wrong data '%.5s'\n", ptr );
1710c2c66affSColin Finck GlobalUnlock( h );
1711c2c66affSColin Finck trace( "private %p\n", h );
1712c2c66affSColin Finck h = GetClipboardData( CF_BITMAP );
1713c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1714c2c66affSColin Finck ok( GetObjectW( h, sizeof(bm), &bm ) == sizeof(bm), "GetObject %p failed\n", h );
1715c2c66affSColin Finck ok( bm.bmWidth == 13 && bm.bmHeight == 17, "wrong bitmap %ux%u\n", bm.bmWidth, bm.bmHeight );
1716c2c66affSColin Finck trace( "bitmap %p\n", h );
1717c2c66affSColin Finck h = GetClipboardData( CF_DSPBITMAP );
1718c2c66affSColin Finck ok( !GetObjectType( h ), "expected invalid object %p\n", h );
1719c2c66affSColin Finck trace( "bitmap2 %p\n", h );
1720c2c66affSColin Finck h = GetClipboardData( CF_PALETTE );
1721c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1722c2c66affSColin Finck ok( GetPaletteEntries( h, 0, 1, &entry ) == 1, "GetPaletteEntries %p failed\n", h );
1723c2c66affSColin Finck ok( entry.peRed == 0x12 && entry.peGreen == 0x34 && entry.peBlue == 0x56,
1724c2c66affSColin Finck "wrong color %02x,%02x,%02x\n", entry.peRed, entry.peGreen, entry.peBlue );
1725c2c66affSColin Finck trace( "palette %p\n", h );
1726c2c66affSColin Finck h = GetClipboardData( CF_METAFILEPICT );
1727c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1728c2c66affSColin Finck #ifdef __REACTOS__
1729c2c66affSColin Finck if (h != NULL)
1730c2c66affSColin Finck #endif
1731c2c66affSColin Finck ok( GetObjectType( ((METAFILEPICT *)h)->hMF ) == OBJ_METAFILE,
1732c2c66affSColin Finck "wrong object %p\n", ((METAFILEPICT *)h)->hMF );
1733c2c66affSColin Finck trace( "metafile %p\n", h );
1734c2c66affSColin Finck h = GetClipboardData( CF_DSPMETAFILEPICT );
1735c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1736c2c66affSColin Finck #ifdef __REACTOS__
1737c2c66affSColin Finck if (h != NULL)
1738c2c66affSColin Finck #endif
1739c2c66affSColin Finck ok( GetObjectType( ((METAFILEPICT *)h)->hMF ) == OBJ_METAFILE,
1740c2c66affSColin Finck "wrong object %p\n", ((METAFILEPICT *)h)->hMF );
1741c2c66affSColin Finck trace( "metafile2 %p\n", h );
1742c2c66affSColin Finck h = GetClipboardData( CF_ENHMETAFILE );
1743c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1744c2c66affSColin Finck ok( GetEnhMetaFileBits( h, sizeof(buffer), buffer ) > sizeof(ENHMETAHEADER),
1745c2c66affSColin Finck "GetEnhMetaFileBits failed on %p\n", h );
1746c2c66affSColin Finck ok( ((ENHMETAHEADER *)buffer)->nRecords == 3,
1747c2c66affSColin Finck "wrong records %u\n", ((ENHMETAHEADER *)buffer)->nRecords );
1748c2c66affSColin Finck trace( "enhmetafile %p\n", h );
1749c2c66affSColin Finck h = GetClipboardData( CF_DSPENHMETAFILE );
1750c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1751c2c66affSColin Finck ok( GetEnhMetaFileBits( h, sizeof(buffer), buffer ) > sizeof(ENHMETAHEADER),
1752c2c66affSColin Finck "GetEnhMetaFileBits failed on %p\n", h );
1753c2c66affSColin Finck ok( ((ENHMETAHEADER *)buffer)->nRecords == 3,
1754c2c66affSColin Finck "wrong records %u\n", ((ENHMETAHEADER *)buffer)->nRecords );
1755c2c66affSColin Finck trace( "enhmetafile2 %p\n", h );
1756c2c66affSColin Finck h = GetClipboardData( CF_DIB );
1757c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1758c2c66affSColin Finck h = GetClipboardData( CF_DIBV5 );
1759c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1760c2c66affSColin Finck r = CloseClipboard();
1761c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1762c2c66affSColin Finck }
1763c2c66affSColin Finck
test_handles_process_open(const char * str)1764c2c66affSColin Finck static void test_handles_process_open( const char *str )
1765c2c66affSColin Finck {
1766c2c66affSColin Finck HANDLE h, text = GlobalAlloc( GMEM_DDESHARE|GMEM_MOVEABLE, strlen(str) + 1 );
1767c2c66affSColin Finck char *ptr = GlobalLock( text );
1768c2c66affSColin Finck
1769c2c66affSColin Finck strcpy( ptr, str );
1770c2c66affSColin Finck GlobalUnlock( text );
1771c2c66affSColin Finck
1772c2c66affSColin Finck /* clipboard already open by parent process */
1773c2c66affSColin Finck h = SetClipboardData( CF_TEXT, text );
1774c2c66affSColin Finck ok( h == text, "wrong mem %p / %p\n", h, text );
1775c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1776c2c66affSColin Finck }
1777c2c66affSColin Finck
test_handles_process_dib(const char * str)1778c2c66affSColin Finck static void test_handles_process_dib( const char *str )
1779c2c66affSColin Finck {
1780c2c66affSColin Finck BOOL r;
1781c2c66affSColin Finck HANDLE h;
1782c2c66affSColin Finck
1783c2c66affSColin Finck r = OpenClipboard( 0 );
1784c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1785c2c66affSColin Finck h = GetClipboardData( CF_BITMAP );
1786c2c66affSColin Finck ok( !GetObjectType( h ), "expected invalid object %p\n", h );
1787c2c66affSColin Finck trace( "dibsection %p\n", h );
1788c2c66affSColin Finck r = CloseClipboard();
1789c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1790c2c66affSColin Finck }
1791c2c66affSColin Finck
test_data_handles(void)1792c2c66affSColin Finck static void test_data_handles(void)
1793c2c66affSColin Finck {
1794c2c66affSColin Finck BOOL r;
1795c2c66affSColin Finck char *ptr;
1796c2c66affSColin Finck HANDLE h, text;
1797c2c66affSColin Finck HWND hwnd = CreateWindowA( "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL );
1798c2c66affSColin Finck BITMAPINFO bmi;
1799c2c66affSColin Finck void *bits;
1800c2c66affSColin Finck
1801c2c66affSColin Finck ok( hwnd != 0, "window creation failed\n" );
1802c2c66affSColin Finck format_id = RegisterClipboardFormatA( "my_cool_clipboard_format" );
1803c2c66affSColin Finck test_handles( 0 );
1804c2c66affSColin Finck test_handles( GetDesktopWindow() );
1805c2c66affSColin Finck test_handles( hwnd );
1806c2c66affSColin Finck run_thread( test_handles_thread, hwnd, __LINE__ );
1807c2c66affSColin Finck
1808c2c66affSColin Finck bitmap = CreateBitmap( 13, 17, 1, 1, NULL );
1809c2c66affSColin Finck bitmap2 = CreateBitmap( 10, 10, 1, 1, NULL );
1810c2c66affSColin Finck palette = CreatePalette( &logpalette );
1811c2c66affSColin Finck
1812c2c66affSColin Finck r = OpenClipboard( hwnd );
1813c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1814c2c66affSColin Finck r = EmptyClipboard();
1815c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1816c2c66affSColin Finck h = SetClipboardData( CF_TEXT, create_textA() );
1817c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1818c2c66affSColin Finck h = SetClipboardData( format_id, create_textA() );
1819c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1820c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap );
1821c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1822c2c66affSColin Finck h = SetClipboardData( CF_DSPBITMAP, bitmap2 );
1823c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1824c2c66affSColin Finck h = SetClipboardData( CF_PALETTE, palette );
1825c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_PAL, "expected palette %p\n", h );
1826c2c66affSColin Finck h = SetClipboardData( CF_METAFILEPICT, create_metafile() );
1827c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1828c2c66affSColin Finck trace( "metafile %p\n", h );
1829c2c66affSColin Finck h = SetClipboardData( CF_DSPMETAFILEPICT, create_metafile() );
1830c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1831c2c66affSColin Finck trace( "metafile2 %p\n", h );
1832c2c66affSColin Finck h = SetClipboardData( CF_ENHMETAFILE, create_emf() );
1833c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1834c2c66affSColin Finck trace( "enhmetafile %p\n", h );
1835c2c66affSColin Finck h = SetClipboardData( CF_DSPENHMETAFILE, create_emf() );
1836c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_ENHMETAFILE, "expected enhmetafile %p\n", h );
1837c2c66affSColin Finck trace( "enhmetafile2 %p\n", h );
1838c2c66affSColin Finck h = SetClipboardData( CF_GDIOBJFIRST + 3, create_textA() );
1839c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1840c2c66affSColin Finck h = SetClipboardData( CF_PRIVATEFIRST + 7, create_textA() );
1841c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1842c2c66affSColin Finck r = CloseClipboard();
1843c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1844c2c66affSColin Finck
1845c2c66affSColin Finck run_thread( test_handles_thread2, 0, __LINE__ );
1846c2c66affSColin Finck run_process( "handles test" );
1847c2c66affSColin Finck
1848c2c66affSColin Finck r = OpenClipboard( hwnd );
1849c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1850c2c66affSColin Finck h = GetClipboardData( CF_TEXT );
1851c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1852c2c66affSColin Finck h = GetClipboardData( format_id );
1853c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1854c2c66affSColin Finck h = GetClipboardData( CF_GDIOBJFIRST + 3 );
1855c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1856c2c66affSColin Finck h = GetClipboardData( CF_PRIVATEFIRST + 7 );
1857c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1858c2c66affSColin Finck
1859c2c66affSColin Finck r = EmptyClipboard();
1860c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1861c2c66affSColin Finck text = create_textA();
1862c2c66affSColin Finck h = SetClipboardData( CF_TEXT, text );
1863c2c66affSColin Finck ok( is_moveable( h ), "expected moveable mem %p\n", h );
1864c2c66affSColin Finck
1865c2c66affSColin Finck run_process( "handles_open foobar" );
1866c2c66affSColin Finck
1867c2c66affSColin Finck ok( is_moveable( text ), "expected moveable mem %p\n", text );
1868c2c66affSColin Finck h = GetClipboardData( CF_TEXT );
1869c2c66affSColin Finck ok( is_fixed( h ), "expected fixed mem %p\n", h );
1870c2c66affSColin Finck ok( is_moveable( text ), "expected moveable mem %p\n", text );
1871c2c66affSColin Finck ptr = GlobalLock( h );
1872c2c66affSColin Finck ok( !strcmp( ptr, "foobar" ), "wrong data '%.8s'\n", ptr );
1873c2c66affSColin Finck GlobalUnlock( h );
1874c2c66affSColin Finck
1875c2c66affSColin Finck r = EmptyClipboard();
1876c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1877c2c66affSColin Finck ok( is_fixed( h ), "expected free mem %p\n", h );
1878c2c66affSColin Finck ok( is_freed( text ) || broken( is_moveable(text) ), /* w2003, w2008 */
1879c2c66affSColin Finck "expected free mem %p\n", text );
1880c2c66affSColin Finck r = CloseClipboard();
1881c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1882c2c66affSColin Finck
1883c2c66affSColin Finck /* test CF_BITMAP with a DIB section */
1884c2c66affSColin Finck memset( &bmi, 0, sizeof(bmi) );
1885c2c66affSColin Finck bmi.bmiHeader.biSize = sizeof( bmi.bmiHeader );
1886c2c66affSColin Finck bmi.bmiHeader.biWidth = 29;
1887c2c66affSColin Finck bmi.bmiHeader.biHeight = 13;
1888c2c66affSColin Finck bmi.bmiHeader.biPlanes = 1;
1889c2c66affSColin Finck bmi.bmiHeader.biBitCount = 32;
1890c2c66affSColin Finck bitmap = CreateDIBSection( 0, &bmi, DIB_RGB_COLORS, &bits, 0, 0 );
1891c2c66affSColin Finck
1892c2c66affSColin Finck r = OpenClipboard( hwnd );
1893c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1894c2c66affSColin Finck r = EmptyClipboard();
1895c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1896c2c66affSColin Finck h = SetClipboardData( CF_BITMAP, bitmap );
1897c2c66affSColin Finck ok( GetObjectType( h ) == OBJ_BITMAP, "expected bitmap %p\n", h );
1898c2c66affSColin Finck trace( "dibsection %p\n", h );
1899c2c66affSColin Finck r = CloseClipboard();
1900c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1901c2c66affSColin Finck
1902c2c66affSColin Finck run_process( "handles_dib dummy" );
1903c2c66affSColin Finck
1904c2c66affSColin Finck r = OpenClipboard( hwnd );
1905c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1906c2c66affSColin Finck ok( GetObjectType( bitmap ) == OBJ_BITMAP, "expected bitmap %p\n", bitmap );
1907c2c66affSColin Finck r = EmptyClipboard();
1908c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1909c2c66affSColin Finck ok( !GetObjectType( bitmap ), "expected deleted %p\n", bitmap );
1910c2c66affSColin Finck r = CloseClipboard();
1911c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1912c2c66affSColin Finck
1913c2c66affSColin Finck DestroyWindow( hwnd );
1914c2c66affSColin Finck }
1915c2c66affSColin Finck
test_GetUpdatedClipboardFormats(void)1916c2c66affSColin Finck static void test_GetUpdatedClipboardFormats(void)
1917c2c66affSColin Finck {
1918c2c66affSColin Finck BOOL r;
1919c2c66affSColin Finck UINT count, formats[256];
1920c2c66affSColin Finck
1921c2c66affSColin Finck if (!pGetUpdatedClipboardFormats)
1922c2c66affSColin Finck {
1923c2c66affSColin Finck win_skip( "GetUpdatedClipboardFormats not supported\n" );
1924c2c66affSColin Finck return;
1925c2c66affSColin Finck }
1926c2c66affSColin Finck
1927c2c66affSColin Finck count = 0xdeadbeef;
1928c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 0, &count );
1929c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1930c2c66affSColin Finck ok( !count, "wrong count %u\n", count );
1931c2c66affSColin Finck
1932c2c66affSColin Finck count = 0xdeadbeef;
1933c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 256, &count );
1934c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1935c2c66affSColin Finck ok( !count, "wrong count %u\n", count );
1936c2c66affSColin Finck
1937c2c66affSColin Finck SetLastError( 0xdeadbeef );
1938c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, NULL );
1939c2c66affSColin Finck ok( !r, "succeeded\n" );
1940c2c66affSColin Finck ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1941c2c66affSColin Finck
1942c2c66affSColin Finck count = 0xdeadbeef;
1943c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count );
1944c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1945c2c66affSColin Finck ok( !count, "wrong count %u\n", count );
1946c2c66affSColin Finck
1947c2c66affSColin Finck r = OpenClipboard( 0 );
1948c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1949c2c66affSColin Finck r = EmptyClipboard();
1950c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1951c2c66affSColin Finck
1952c2c66affSColin Finck count = 0xdeadbeef;
1953c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count );
1954c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1955c2c66affSColin Finck ok( !count, "wrong count %u\n", count );
1956c2c66affSColin Finck
1957c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, 0 );
1958c2c66affSColin Finck
1959c2c66affSColin Finck count = 0xdeadbeef;
1960c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) );
1961c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count );
1962c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1963c2c66affSColin Finck ok( count == 1, "wrong count %u\n", count );
1964c2c66affSColin Finck ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] );
1965c2c66affSColin Finck ok( formats[1] == 0xcccccccc, "wrong format %u\n", formats[1] );
1966c2c66affSColin Finck
1967c2c66affSColin Finck SetClipboardData( CF_TEXT, 0 );
1968c2c66affSColin Finck count = 0xdeadbeef;
1969c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) );
1970c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count );
1971c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1972c2c66affSColin Finck ok( count == 2, "wrong count %u\n", count );
1973c2c66affSColin Finck ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] );
1974c2c66affSColin Finck ok( formats[1] == CF_TEXT, "wrong format %u\n", formats[1] );
1975c2c66affSColin Finck ok( formats[2] == 0xcccccccc, "wrong format %u\n", formats[2] );
1976c2c66affSColin Finck
1977c2c66affSColin Finck SetLastError( 0xdeadbeef );
1978c2c66affSColin Finck count = 0xdeadbeef;
1979c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 0, &count );
1980c2c66affSColin Finck ok( !r, "succeeded\n" );
1981c2c66affSColin Finck ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() );
1982c2c66affSColin Finck ok( count == 2, "wrong count %u\n", count );
1983c2c66affSColin Finck
1984c2c66affSColin Finck SetLastError( 0xdeadbeef );
1985c2c66affSColin Finck count = 0xdeadbeef;
1986c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 1, &count );
1987c2c66affSColin Finck ok( !r, "succeeded\n" );
1988c2c66affSColin Finck ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() );
1989c2c66affSColin Finck ok( count == 2, "wrong count %u\n", count );
1990c2c66affSColin Finck
1991c2c66affSColin Finck r = CloseClipboard();
1992c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1993c2c66affSColin Finck
1994c2c66affSColin Finck count = 0xdeadbeef;
1995c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) );
1996c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 256, &count );
1997c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
1998c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count );
1999c2c66affSColin Finck ok( formats[0] == CF_UNICODETEXT, "wrong format %u\n", formats[0] );
2000c2c66affSColin Finck ok( formats[1] == CF_TEXT, "wrong format %u\n", formats[1] );
2001c2c66affSColin Finck ok( formats[2] == CF_LOCALE, "wrong format %u\n", formats[2] );
2002c2c66affSColin Finck ok( formats[3] == CF_OEMTEXT, "wrong format %u\n", formats[3] );
2003c2c66affSColin Finck ok( formats[4] == 0xcccccccc, "wrong format %u\n", formats[4] );
2004c2c66affSColin Finck
2005c2c66affSColin Finck count = 0xdeadbeef;
2006c2c66affSColin Finck memset( formats, 0xcc, sizeof(formats) );
2007c2c66affSColin Finck r = pGetUpdatedClipboardFormats( formats, 2, &count );
2008c2c66affSColin Finck ok( !r, "gle %d\n", GetLastError() );
2009c2c66affSColin Finck ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() );
2010c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count );
2011c2c66affSColin Finck ok( formats[0] == 0xcccccccc, "wrong format %u\n", formats[0] );
2012c2c66affSColin Finck
2013c2c66affSColin Finck count = 0xdeadbeef;
2014c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 256, &count );
2015c2c66affSColin Finck ok( !r, "gle %d\n", GetLastError() );
2016c2c66affSColin Finck ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
2017c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count );
2018c2c66affSColin Finck
2019c2c66affSColin Finck count = 0xdeadbeef;
2020c2c66affSColin Finck r = pGetUpdatedClipboardFormats( NULL, 256, &count );
2021c2c66affSColin Finck ok( !r, "gle %d\n", GetLastError() );
2022c2c66affSColin Finck ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
2023c2c66affSColin Finck ok( count == 4, "wrong count %u\n", count );
2024c2c66affSColin Finck }
2025c2c66affSColin Finck
2026c2c66affSColin Finck static const struct
2027c2c66affSColin Finck {
2028c2c66affSColin Finck char strA[12];
2029c2c66affSColin Finck WCHAR strW[12];
2030c2c66affSColin Finck UINT len;
2031c2c66affSColin Finck } test_data[] =
2032c2c66affSColin Finck {
2033c2c66affSColin Finck { "foo", {0}, 3 }, /* 0 */
2034c2c66affSColin Finck { "foo", {0}, 4 },
2035c2c66affSColin Finck { "foo\0bar", {0}, 7 },
2036c2c66affSColin Finck { "foo\0bar", {0}, 8 },
2037c2c66affSColin Finck { "", {'f','o','o'}, 3 * sizeof(WCHAR) },
2038c2c66affSColin Finck { "", {'f','o','o',0}, 4 * sizeof(WCHAR) }, /* 5 */
2039c2c66affSColin Finck { "", {'f','o','o',0,'b','a','r'}, 7 * sizeof(WCHAR) },
2040c2c66affSColin Finck { "", {'f','o','o',0,'b','a','r',0}, 8 * sizeof(WCHAR) },
2041c2c66affSColin Finck { "", {'f','o','o'}, 1 },
2042c2c66affSColin Finck { "", {'f','o','o'}, 2 },
2043c2c66affSColin Finck { "", {'f','o','o'}, 5 }, /* 10 */
2044c2c66affSColin Finck { "", {'f','o','o',0}, 7 },
2045c2c66affSColin Finck { "", {'f','o','o',0}, 9 },
2046c2c66affSColin Finck };
2047c2c66affSColin Finck
test_string_data(void)2048c2c66affSColin Finck static void test_string_data(void)
2049c2c66affSColin Finck {
2050c2c66affSColin Finck UINT i;
2051c2c66affSColin Finck BOOL r;
2052c2c66affSColin Finck HANDLE data;
2053c2c66affSColin Finck char cmd[16];
2054c2c66affSColin Finck char bufferA[12];
2055c2c66affSColin Finck WCHAR bufferW[12];
2056c2c66affSColin Finck
2057*7a62c32bSAmine Khaldi for (i = 0; i < ARRAY_SIZE(test_data); i++)
2058c2c66affSColin Finck {
2059c2c66affSColin Finck /* 1-byte Unicode strings crash on Win64 */
2060c2c66affSColin Finck #ifdef _WIN64
2061c2c66affSColin Finck if (!test_data[i].strA[0] && test_data[i].len < sizeof(WCHAR)) continue;
2062c2c66affSColin Finck #endif
2063c2c66affSColin Finck r = OpenClipboard( 0 );
2064c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
2065c2c66affSColin Finck r = EmptyClipboard();
2066c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
2067c2c66affSColin Finck data = GlobalAlloc( GMEM_FIXED, test_data[i].len );
2068c2c66affSColin Finck if (test_data[i].strA[0])
2069c2c66affSColin Finck {
2070c2c66affSColin Finck memcpy( data, test_data[i].strA, test_data[i].len );
2071c2c66affSColin Finck SetClipboardData( CF_TEXT, data );
2072c2c66affSColin Finck memcpy( bufferA, test_data[i].strA, test_data[i].len );
2073c2c66affSColin Finck bufferA[test_data[i].len - 1] = 0;
2074c2c66affSColin Finck ok( !memcmp( data, bufferA, test_data[i].len ),
2075c2c66affSColin Finck "%u: wrong data %.*s\n", i, test_data[i].len, (char *)data );
2076c2c66affSColin Finck }
2077c2c66affSColin Finck else
2078c2c66affSColin Finck {
2079c2c66affSColin Finck memcpy( data, test_data[i].strW, test_data[i].len );
2080c2c66affSColin Finck SetClipboardData( CF_UNICODETEXT, data );
2081c2c66affSColin Finck memcpy( bufferW, test_data[i].strW, test_data[i].len );
2082c2c66affSColin Finck bufferW[(test_data[i].len + 1) / sizeof(WCHAR) - 1] = 0;
2083c2c66affSColin Finck ok( !memcmp( data, bufferW, test_data[i].len ),
2084c2c66affSColin Finck "%u: wrong data %s\n", i, wine_dbgstr_wn( data, (test_data[i].len + 1) / sizeof(WCHAR) ));
2085c2c66affSColin Finck }
2086c2c66affSColin Finck r = CloseClipboard();
2087c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
2088c2c66affSColin Finck sprintf( cmd, "string_data %u", i );
2089c2c66affSColin Finck run_process( cmd );
2090c2c66affSColin Finck }
2091c2c66affSColin Finck }
2092c2c66affSColin Finck
test_string_data_process(int i)2093c2c66affSColin Finck static void test_string_data_process( int i )
2094c2c66affSColin Finck {
2095c2c66affSColin Finck BOOL r;
2096c2c66affSColin Finck HANDLE data;
2097c2c66affSColin Finck UINT len, len2;
2098c2c66affSColin Finck char bufferA[12];
2099c2c66affSColin Finck WCHAR bufferW[12];
2100c2c66affSColin Finck
2101c2c66affSColin Finck r = OpenClipboard( 0 );
2102c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
2103c2c66affSColin Finck if (test_data[i].strA[0])
2104c2c66affSColin Finck {
2105c2c66affSColin Finck data = GetClipboardData( CF_TEXT );
2106c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i );
2107c2c66affSColin Finck len = GlobalSize( data );
2108c2c66affSColin Finck ok( len == test_data[i].len, "%u: wrong size %u / %u\n", i, len, test_data[i].len );
2109c2c66affSColin Finck memcpy( bufferA, test_data[i].strA, test_data[i].len );
2110c2c66affSColin Finck bufferA[test_data[i].len - 1] = 0;
2111c2c66affSColin Finck ok( !memcmp( data, bufferA, len ), "%u: wrong data %.*s\n", i, len, (char *)data );
2112c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT );
2113c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i );
2114c2c66affSColin Finck len = GlobalSize( data );
2115c2c66affSColin Finck len2 = MultiByteToWideChar( CP_ACP, 0, bufferA, test_data[i].len, bufferW, 12 );
2116c2c66affSColin Finck ok( len == len2 * sizeof(WCHAR), "%u: wrong size %u / %u\n", i, len, len2 );
2117c2c66affSColin Finck ok( !memcmp( data, bufferW, len ), "%u: wrong data %s\n", i, wine_dbgstr_wn( data, len2 ));
2118c2c66affSColin Finck }
2119c2c66affSColin Finck else
2120c2c66affSColin Finck {
2121c2c66affSColin Finck data = GetClipboardData( CF_UNICODETEXT );
2122c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i );
2123c2c66affSColin Finck len = GlobalSize( data );
2124c2c66affSColin Finck ok( len == test_data[i].len, "%u: wrong size %u / %u\n", i, len, test_data[i].len );
2125c2c66affSColin Finck memcpy( bufferW, test_data[i].strW, test_data[i].len );
2126c2c66affSColin Finck bufferW[(test_data[i].len + 1) / sizeof(WCHAR) - 1] = 0;
2127c2c66affSColin Finck ok( !memcmp( data, bufferW, len ),
2128c2c66affSColin Finck "%u: wrong data %s\n", i, wine_dbgstr_wn( data, (len + 1) / sizeof(WCHAR) ));
2129c2c66affSColin Finck data = GetClipboardData( CF_TEXT );
2130c2c66affSColin Finck if (test_data[i].len >= sizeof(WCHAR))
2131c2c66affSColin Finck {
2132c2c66affSColin Finck ok( data != 0, "%u: could not get data\n", i );
2133c2c66affSColin Finck len = GlobalSize( data );
2134c2c66affSColin Finck len2 = WideCharToMultiByte( CP_ACP, 0, bufferW, test_data[i].len / sizeof(WCHAR),
2135c2c66affSColin Finck bufferA, 12, NULL, NULL );
2136c2c66affSColin Finck bufferA[len2 - 1] = 0;
2137c2c66affSColin Finck ok( len == len2, "%u: wrong size %u / %u\n", i, len, len2 );
2138c2c66affSColin Finck ok( !memcmp( data, bufferA, len ), "%u: wrong data %.*s\n", i, len, (char *)data );
2139c2c66affSColin Finck }
2140c2c66affSColin Finck else
2141c2c66affSColin Finck {
2142c2c66affSColin Finck ok( !data, "%u: got data for empty string\n", i );
2143c2c66affSColin Finck ok( IsClipboardFormatAvailable( CF_TEXT ), "%u: text not available\n", i );
2144c2c66affSColin Finck }
2145c2c66affSColin Finck }
2146c2c66affSColin Finck r = CloseClipboard();
2147c2c66affSColin Finck ok( r, "gle %d\n", GetLastError() );
2148c2c66affSColin Finck }
2149c2c66affSColin Finck
START_TEST(clipboard)2150c2c66affSColin Finck START_TEST(clipboard)
2151c2c66affSColin Finck {
2152c2c66affSColin Finck char **argv;
2153c2c66affSColin Finck int argc = winetest_get_mainargs( &argv );
2154c2c66affSColin Finck HMODULE mod = GetModuleHandleA( "user32" );
2155c2c66affSColin Finck
2156c2c66affSColin Finck argv0 = argv[0];
2157c2c66affSColin Finck pAddClipboardFormatListener = (void *)GetProcAddress( mod, "AddClipboardFormatListener" );
2158c2c66affSColin Finck pRemoveClipboardFormatListener = (void *)GetProcAddress( mod, "RemoveClipboardFormatListener" );
2159c2c66affSColin Finck pGetUpdatedClipboardFormats = (void *)GetProcAddress( mod, "GetUpdatedClipboardFormats" );
2160c2c66affSColin Finck
2161c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "set_clipboard_data" ))
2162c2c66affSColin Finck {
2163c2c66affSColin Finck set_clipboard_data_process( atoi( argv[3] ));
2164c2c66affSColin Finck return;
2165c2c66affSColin Finck }
2166c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "grab_clipboard" ))
2167c2c66affSColin Finck {
2168c2c66affSColin Finck grab_clipboard_process( atoi( argv[3] ));
2169c2c66affSColin Finck return;
2170c2c66affSColin Finck }
2171c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "handles" ))
2172c2c66affSColin Finck {
2173c2c66affSColin Finck test_handles_process( argv[3] );
2174c2c66affSColin Finck return;
2175c2c66affSColin Finck }
2176c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "handles_open" ))
2177c2c66affSColin Finck {
2178c2c66affSColin Finck test_handles_process_open( argv[3] );
2179c2c66affSColin Finck return;
2180c2c66affSColin Finck }
2181c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "handles_dib" ))
2182c2c66affSColin Finck {
2183c2c66affSColin Finck test_handles_process_dib( argv[3] );
2184c2c66affSColin Finck return;
2185c2c66affSColin Finck }
2186c2c66affSColin Finck if (argc == 4 && !strcmp( argv[2], "string_data" ))
2187c2c66affSColin Finck {
2188c2c66affSColin Finck test_string_data_process( atoi( argv[3] ));
2189c2c66affSColin Finck return;
2190c2c66affSColin Finck }
2191c2c66affSColin Finck if (argc == 3 && !strcmp( argv[2], "get_clipboard_data" ))
2192c2c66affSColin Finck {
2193c2c66affSColin Finck get_clipboard_data_process( );
2194c2c66affSColin Finck return;
2195c2c66affSColin Finck }
2196c2c66affSColin Finck
2197c2c66affSColin Finck test_RegisterClipboardFormatA();
2198c2c66affSColin Finck test_ClipboardOwner();
2199c2c66affSColin Finck test_synthesized();
2200c2c66affSColin Finck test_messages();
2201c2c66affSColin Finck test_data_handles();
2202c2c66affSColin Finck test_GetUpdatedClipboardFormats();
2203c2c66affSColin Finck test_string_data();
2204c2c66affSColin Finck }
2205