[UXTHEME_WINETEST] Sync with Wine Staging 2.2. CORE-12823
[reactos.git] / rostests / winetests / uxtheme / system.c
1 /* Unit test suite for uxtheme API functions
2 *
3 * Copyright 2006 Paul Vriens
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 */
20
21 #include <stdarg.h>
22
23 #include "windows.h"
24 #include "vfwmsgs.h"
25 #include "uxtheme.h"
26
27 #include "wine/test.h"
28
29 static HTHEME (WINAPI * pOpenThemeDataEx)(HWND, LPCWSTR, DWORD);
30 static HPAINTBUFFER (WINAPI *pBeginBufferedPaint)(HDC, const RECT *, BP_BUFFERFORMAT, BP_PAINTPARAMS *, HDC *);
31 static HRESULT (WINAPI *pBufferedPaintClear)(HPAINTBUFFER, const RECT *);
32 static HRESULT (WINAPI *pEndBufferedPaint)(HPAINTBUFFER, BOOL);
33 static HRESULT (WINAPI *pGetBufferedPaintBits)(HPAINTBUFFER, RGBQUAD **, int *);
34 static HDC (WINAPI *pGetBufferedPaintDC)(HPAINTBUFFER);
35 static HDC (WINAPI *pGetBufferedPaintTargetDC)(HPAINTBUFFER);
36 static HRESULT (WINAPI *pGetBufferedPaintTargetRect)(HPAINTBUFFER, RECT *);
37
38 static void init_funcs(void)
39 {
40 HMODULE hUxtheme = GetModuleHandleA("uxtheme.dll");
41
42 #define UXTHEME_GET_PROC(func) p ## func = (void*)GetProcAddress(hUxtheme, #func)
43 UXTHEME_GET_PROC(BeginBufferedPaint);
44 UXTHEME_GET_PROC(BufferedPaintClear);
45 UXTHEME_GET_PROC(EndBufferedPaint);
46 UXTHEME_GET_PROC(GetBufferedPaintBits);
47 UXTHEME_GET_PROC(GetBufferedPaintDC);
48 UXTHEME_GET_PROC(GetBufferedPaintTargetDC);
49 UXTHEME_GET_PROC(GetBufferedPaintTargetRect);
50 UXTHEME_GET_PROC(BufferedPaintClear);
51
52 UXTHEME_GET_PROC(OpenThemeDataEx);
53 #undef UXTHEME_GET_PROC
54 }
55
56 static void test_IsThemed(void)
57 {
58 BOOL bThemeActive;
59 BOOL bAppThemed;
60 BOOL bTPDefined;
61
62 bThemeActive = IsThemeActive();
63 trace("Theming is %s\n", (bThemeActive) ? "active" : "inactive");
64
65 bAppThemed = IsAppThemed();
66 trace("Test executable is %s\n", (bAppThemed) ? "themed" : "not themed");
67
68 SetLastError(0xdeadbeef);
69 bTPDefined = IsThemePartDefined(NULL, 0 , 0);
70 ok( bTPDefined == FALSE, "Expected FALSE\n");
71 ok( GetLastError() == E_HANDLE,
72 "Expected E_HANDLE, got 0x%08x\n",
73 GetLastError());
74 }
75
76 static void test_GetWindowTheme(void)
77 {
78 HTHEME hTheme;
79 HWND hWnd;
80 BOOL bDestroyed;
81
82 SetLastError(0xdeadbeef);
83 hTheme = GetWindowTheme(NULL);
84 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
85 todo_wine
86 ok( GetLastError() == E_HANDLE,
87 "Expected E_HANDLE, got 0x%08x\n",
88 GetLastError());
89
90 /* Only do the bare minimum to get a valid hwnd */
91 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
92 if (!hWnd) return;
93
94 SetLastError(0xdeadbeef);
95 hTheme = GetWindowTheme(hWnd);
96 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
97 ok( GetLastError() == 0xdeadbeef,
98 "Expected 0xdeadbeef, got 0x%08x\n",
99 GetLastError());
100
101 bDestroyed = DestroyWindow(hWnd);
102 if (!bDestroyed)
103 trace("Window %p couldn't be destroyed : 0x%08x\n",
104 hWnd, GetLastError());
105 }
106
107 static void test_SetWindowTheme(void)
108 {
109 HRESULT hRes;
110 HWND hWnd;
111 BOOL bDestroyed;
112
113 hRes = SetWindowTheme(NULL, NULL, NULL);
114 todo_wine
115 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
116
117 /* Only do the bare minimum to get a valid hwnd */
118 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
119 if (!hWnd) return;
120
121 hRes = SetWindowTheme(hWnd, NULL, NULL);
122 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
123
124 bDestroyed = DestroyWindow(hWnd);
125 if (!bDestroyed)
126 trace("Window %p couldn't be destroyed : 0x%08x\n",
127 hWnd, GetLastError());
128 }
129
130 static void test_OpenThemeData(void)
131 {
132 HTHEME hTheme, hTheme2;
133 HWND hWnd;
134 BOOL bThemeActive;
135 HRESULT hRes;
136 BOOL bDestroyed;
137 BOOL bTPDefined;
138
139 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 };
140 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 };
141 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 };
142 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
143
144 bThemeActive = IsThemeActive();
145
146 /* All NULL */
147 SetLastError(0xdeadbeef);
148 hTheme = OpenThemeData(NULL, NULL);
149 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
150 ok( GetLastError() == E_POINTER,
151 "Expected GLE() to be E_POINTER, got 0x%08x\n",
152 GetLastError());
153
154 /* A NULL hWnd and an invalid classlist */
155 SetLastError(0xdeadbeef);
156 hTheme = OpenThemeData(NULL, szInvalidClassList);
157 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
158 todo_wine
159 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
160 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
161 GetLastError());
162
163 SetLastError(0xdeadbeef);
164 hTheme = OpenThemeData(NULL, szClassList);
165 if (bThemeActive)
166 {
167 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
168 todo_wine
169 ok( GetLastError() == ERROR_SUCCESS,
170 "Expected ERROR_SUCCESS, got 0x%08x\n",
171 GetLastError());
172 }
173 else
174 {
175 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
176 todo_wine
177 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
178 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
179 GetLastError());
180 }
181
182 /* Only do the bare minimum to get a valid hdc */
183 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
184 if (!hWnd) return;
185
186 SetLastError(0xdeadbeef);
187 hTheme = OpenThemeData(hWnd, NULL);
188 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
189 ok( GetLastError() == E_POINTER,
190 "Expected GLE() to be E_POINTER, got 0x%08x\n",
191 GetLastError());
192
193 SetLastError(0xdeadbeef);
194 hTheme = OpenThemeData(hWnd, szInvalidClassList);
195 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
196 todo_wine
197 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
198 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
199 GetLastError());
200
201 /* Close invalid handle */
202 hRes = CloseThemeData((HTHEME)0xdeadbeef);
203 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
204
205 if (!bThemeActive)
206 {
207 SetLastError(0xdeadbeef);
208 hTheme = OpenThemeData(hWnd, szButtonClassList);
209 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
210 todo_wine
211 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
212 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
213 GetLastError());
214 skip("No active theme, skipping rest of OpenThemeData tests\n");
215 return;
216 }
217
218 /* Only do the next checks if we have an active theme */
219
220 SetLastError(0xdeadbeef);
221 hTheme = OpenThemeData(hWnd, szButtonClassList);
222 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
223 todo_wine
224 ok( GetLastError() == ERROR_SUCCESS,
225 "Expected ERROR_SUCCESS, got 0x%08x\n",
226 GetLastError());
227
228 /* Test with bUtToN instead of Button */
229 SetLastError(0xdeadbeef);
230 hTheme = OpenThemeData(hWnd, szButtonClassList2);
231 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
232 todo_wine
233 ok( GetLastError() == ERROR_SUCCESS,
234 "Expected ERROR_SUCCESS, got 0x%08x\n",
235 GetLastError());
236
237 SetLastError(0xdeadbeef);
238 hTheme = OpenThemeData(hWnd, szClassList);
239 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
240 todo_wine
241 ok( GetLastError() == ERROR_SUCCESS,
242 "Expected ERROR_SUCCESS, got 0x%08x\n",
243 GetLastError());
244
245 /* GetWindowTheme should return the last handle opened by OpenThemeData */
246 SetLastError(0xdeadbeef);
247 hTheme2 = GetWindowTheme(hWnd);
248 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
249 hTheme, hTheme2);
250 ok( GetLastError() == 0xdeadbeef,
251 "Expected 0xdeadbeef, got 0x%08x\n",
252 GetLastError());
253
254 hRes = CloseThemeData(hTheme);
255 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
256
257 /* Close a second time */
258 hRes = CloseThemeData(hTheme);
259 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
260
261 /* See if closing makes a difference for GetWindowTheme */
262 SetLastError(0xdeadbeef);
263 hTheme2 = NULL;
264 hTheme2 = GetWindowTheme(hWnd);
265 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
266 hTheme, hTheme2);
267 ok( GetLastError() == 0xdeadbeef,
268 "Expected 0xdeadbeef, got 0x%08x\n",
269 GetLastError());
270
271 SetLastError(0xdeadbeef);
272 bTPDefined = IsThemePartDefined(hTheme, 0 , 0);
273 todo_wine
274 {
275 ok( bTPDefined == FALSE, "Expected FALSE\n");
276 ok( GetLastError() == ERROR_SUCCESS,
277 "Expected ERROR_SUCCESS, got 0x%08x\n",
278 GetLastError());
279 }
280
281 bDestroyed = DestroyWindow(hWnd);
282 if (!bDestroyed)
283 trace("Window %p couldn't be destroyed : 0x%08x\n",
284 hWnd, GetLastError());
285 }
286
287 static void test_OpenThemeDataEx(void)
288 {
289 HTHEME hTheme;
290 HWND hWnd;
291 BOOL bThemeActive;
292 BOOL bDestroyed;
293
294 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 };
295 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 };
296 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 };
297 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
298
299 if (!pOpenThemeDataEx)
300 {
301 win_skip("OpenThemeDataEx not available\n");
302 return;
303 }
304
305 bThemeActive = IsThemeActive();
306
307 /* All NULL */
308 SetLastError(0xdeadbeef);
309 hTheme = pOpenThemeDataEx(NULL, NULL, 0);
310 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
311 ok( GetLastError() == E_POINTER,
312 "Expected GLE() to be E_POINTER, got 0x%08x\n",
313 GetLastError());
314
315 /* A NULL hWnd and an invalid classlist without flags */
316 SetLastError(0xdeadbeef);
317 hTheme = pOpenThemeDataEx(NULL, szInvalidClassList, 0);
318 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
319 todo_wine
320 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
321 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
322 GetLastError());
323
324 SetLastError(0xdeadbeef);
325 hTheme = pOpenThemeDataEx(NULL, szClassList, 0);
326 if (bThemeActive)
327 {
328 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
329 todo_wine
330 ok( GetLastError() == ERROR_SUCCESS,
331 "Expected ERROR_SUCCESS, got 0x%08x\n",
332 GetLastError());
333 }
334 else
335 {
336 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
337 todo_wine
338 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
339 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
340 GetLastError());
341 }
342
343 /* Only do the bare minimum to get a valid hdc */
344 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
345 if (!hWnd) return;
346
347 SetLastError(0xdeadbeef);
348 hTheme = pOpenThemeDataEx(hWnd, NULL, 0);
349 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
350 ok( GetLastError() == E_POINTER,
351 "Expected GLE() to be E_POINTER, got 0x%08x\n",
352 GetLastError());
353
354 SetLastError(0xdeadbeef);
355 hTheme = pOpenThemeDataEx(hWnd, szInvalidClassList, 0);
356 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
357 todo_wine
358 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
359 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
360 GetLastError());
361
362 if (!bThemeActive)
363 {
364 SetLastError(0xdeadbeef);
365 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, 0);
366 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
367 todo_wine
368 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
369 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
370 GetLastError());
371 skip("No active theme, skipping rest of OpenThemeDataEx tests\n");
372 return;
373 }
374
375 /* Only do the next checks if we have an active theme */
376
377 SetLastError(0xdeadbeef);
378 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, 0);
379 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
380 todo_wine
381 ok( GetLastError() == ERROR_SUCCESS,
382 "Expected ERROR_SUCCESS, got 0x%08x\n",
383 GetLastError());
384
385 SetLastError(0xdeadbeef);
386 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, OTD_FORCE_RECT_SIZING);
387 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
388 todo_wine
389 ok( GetLastError() == ERROR_SUCCESS,
390 "Expected ERROR_SUCCESS, got 0x%08x\n",
391 GetLastError());
392
393 SetLastError(0xdeadbeef);
394 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, OTD_NONCLIENT);
395 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
396 todo_wine
397 ok( GetLastError() == ERROR_SUCCESS,
398 "Expected ERROR_SUCCESS, got 0x%08x\n",
399 GetLastError());
400
401 SetLastError(0xdeadbeef);
402 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, 0x3);
403 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
404 todo_wine
405 ok( GetLastError() == ERROR_SUCCESS,
406 "Expected ERROR_SUCCESS, got 0x%08x\n",
407 GetLastError());
408
409 /* Test with bUtToN instead of Button */
410 SetLastError(0xdeadbeef);
411 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList2, 0);
412 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
413 todo_wine
414 ok( GetLastError() == ERROR_SUCCESS,
415 "Expected ERROR_SUCCESS, got 0x%08x\n",
416 GetLastError());
417
418 SetLastError(0xdeadbeef);
419 hTheme = pOpenThemeDataEx(hWnd, szClassList, 0);
420 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
421 todo_wine
422 ok( GetLastError() == ERROR_SUCCESS,
423 "Expected ERROR_SUCCESS, got 0x%08x\n",
424 GetLastError());
425
426 bDestroyed = DestroyWindow(hWnd);
427 if (!bDestroyed)
428 trace("Window %p couldn't be destroyed : 0x%08x\n",
429 hWnd, GetLastError());
430 }
431
432 static void test_GetCurrentThemeName(void)
433 {
434 BOOL bThemeActive;
435 HRESULT hRes;
436 WCHAR currentTheme[MAX_PATH];
437 WCHAR currentColor[MAX_PATH];
438 WCHAR currentSize[MAX_PATH];
439
440 bThemeActive = IsThemeActive();
441
442 /* All NULLs */
443 hRes = GetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
444 if (bThemeActive)
445 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
446 else
447 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
448
449 /* Number of characters given is 0 */
450 hRes = GetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
451 if (bThemeActive)
452 ok( hRes == S_OK || broken(hRes == E_FAIL /* WinXP SP1 */), "Expected S_OK, got 0x%08x\n", hRes);
453 else
454 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
455
456 hRes = GetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
457 if (bThemeActive)
458 todo_wine
459 ok(hRes == E_NOT_SUFFICIENT_BUFFER ||
460 broken(hRes == E_FAIL /* WinXP SP1 */),
461 "Expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hRes);
462 else
463 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
464
465 /* The same is true if the number of characters is too small for Color and/or Size */
466 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
467 currentColor, 2,
468 currentSize, sizeof(currentSize) / sizeof(WCHAR));
469 if (bThemeActive)
470 todo_wine
471 ok(hRes == E_NOT_SUFFICIENT_BUFFER ||
472 broken(hRes == E_FAIL /* WinXP SP1 */),
473 "Expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hRes);
474 else
475 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
476
477 /* Given number of characters is correct */
478 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
479 if (bThemeActive)
480 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
481 else
482 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
483
484 /* Given number of characters for the theme name is too large */
485 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0);
486 if (bThemeActive)
487 ok( hRes == E_POINTER || hRes == S_OK, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes);
488 else
489 ok( hRes == E_PROP_ID_UNSUPPORTED ||
490 hRes == E_POINTER, /* win2k3 */
491 "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
492
493 /* The too large case is only for the theme name, not for color name or size name */
494 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
495 currentColor, sizeof(currentTheme),
496 currentSize, sizeof(currentSize) / sizeof(WCHAR));
497 if (bThemeActive)
498 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
499 else
500 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
501
502 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
503 currentColor, sizeof(currentTheme) / sizeof(WCHAR),
504 currentSize, sizeof(currentSize));
505 if (bThemeActive)
506 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
507 else
508 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
509
510 /* Correct call */
511 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
512 currentColor, sizeof(currentColor) / sizeof(WCHAR),
513 currentSize, sizeof(currentSize) / sizeof(WCHAR));
514 if (bThemeActive)
515 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
516 else
517 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
518 }
519
520 static void test_CloseThemeData(void)
521 {
522 HRESULT hRes;
523
524 hRes = CloseThemeData(NULL);
525 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
526 hRes = CloseThemeData(INVALID_HANDLE_VALUE);
527 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
528 }
529
530 static void test_buffered_paint(void)
531 {
532 BP_PAINTPARAMS params = { 0 };
533 BP_BUFFERFORMAT format;
534 HDC target, src, hdc;
535 HPAINTBUFFER buffer;
536 RECT rect, rect2;
537 RGBQUAD *bits;
538 HRESULT hr;
539 int row;
540
541 if (!pBeginBufferedPaint)
542 {
543 win_skip("Buffered painting API is not supported.\n");
544 return;
545 }
546
547 buffer = pBeginBufferedPaint(NULL, NULL, BPBF_COMPATIBLEBITMAP,
548 NULL, NULL);
549 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
550
551 target = CreateCompatibleDC(0);
552 buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP,
553 NULL, NULL);
554 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
555
556 params.cbSize = sizeof(params);
557 buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP,
558 &params, NULL);
559 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
560
561 src = (void *)0xdeadbeef;
562 buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP,
563 &params, &src);
564 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
565 ok(src == NULL, "Unexpected buffered dc %p\n", src);
566
567 /* target rect is mandatory */
568 SetRectEmpty(&rect);
569 src = (void *)0xdeadbeef;
570 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
571 &params, &src);
572 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
573 ok(src == NULL, "Unexpected buffered dc %p\n", src);
574
575 /* inverted rectangle */
576 SetRect(&rect, 10, 0, 5, 5);
577 src = (void *)0xdeadbeef;
578 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
579 &params, &src);
580 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
581 ok(src == NULL, "Unexpected buffered dc %p\n", src);
582
583 SetRect(&rect, 0, 10, 5, 0);
584 src = (void *)0xdeadbeef;
585 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
586 &params, &src);
587 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
588 ok(src == NULL, "Unexpected buffered dc %p\n", src);
589
590 /* valid rectangle, no target dc */
591 SetRect(&rect, 0, 0, 5, 5);
592 src = (void *)0xdeadbeef;
593 buffer = pBeginBufferedPaint(NULL, &rect, BPBF_COMPATIBLEBITMAP,
594 &params, &src);
595 ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
596 ok(src == NULL, "Unexpected buffered dc %p\n", src);
597
598 SetRect(&rect, 0, 0, 5, 5);
599 src = NULL;
600 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
601 &params, &src);
602 ok(buffer != NULL, "Unexpected buffer %p\n", buffer);
603 ok(src != NULL, "Expected buffered dc\n");
604 hr = pEndBufferedPaint(buffer, FALSE);
605 ok(hr == S_OK, "Unexpected return code %#x\n", hr);
606
607 SetRect(&rect, 0, 0, 5, 5);
608 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
609 &params, &src);
610 ok(buffer != NULL, "Unexpected buffer %p\n", buffer);
611
612 /* clearing */
613 hr = pBufferedPaintClear(NULL, NULL);
614 todo_wine
615 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr);
616
617 hr = pBufferedPaintClear(buffer, NULL);
618 todo_wine
619 ok(hr == S_OK, "Unexpected return code %#x\n", hr);
620
621 /* access buffer attributes */
622 hdc = pGetBufferedPaintDC(buffer);
623 ok(hdc == src, "Unexpected hdc, %p, buffered dc %p\n", hdc, src);
624
625 hdc = pGetBufferedPaintTargetDC(buffer);
626 ok(hdc == target, "Unexpected target hdc %p, original %p\n", hdc, target);
627
628 hr = pGetBufferedPaintTargetRect(NULL, NULL);
629 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr);
630
631 hr = pGetBufferedPaintTargetRect(buffer, NULL);
632 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr);
633
634 hr = pGetBufferedPaintTargetRect(NULL, &rect2);
635 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr);
636
637 SetRectEmpty(&rect2);
638 hr = pGetBufferedPaintTargetRect(buffer, &rect2);
639 ok(hr == S_OK, "Unexpected return code %#x\n", hr);
640 ok(EqualRect(&rect, &rect2), "Wrong target rect\n");
641
642 hr = pEndBufferedPaint(buffer, FALSE);
643 ok(hr == S_OK, "Unexpected return code %#x\n", hr);
644
645 /* invalid buffer handle */
646 hr = pEndBufferedPaint(NULL, FALSE);
647 ok(hr == E_INVALIDARG, "Unexpected return code %#x\n", hr);
648
649 hdc = pGetBufferedPaintDC(NULL);
650 ok(hdc == NULL, "Unexpected hdc %p\n", hdc);
651
652 hdc = pGetBufferedPaintTargetDC(NULL);
653 ok(hdc == NULL, "Unexpected target hdc %p\n", hdc);
654
655 hr = pGetBufferedPaintTargetRect(NULL, &rect2);
656 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr);
657
658 hr = pGetBufferedPaintTargetRect(NULL, NULL);
659 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr);
660
661 bits = (void *)0xdeadbeef;
662 row = 10;
663 hr = pGetBufferedPaintBits(NULL, &bits, &row);
664 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr);
665 ok(row == 10, "Unexpected row count %d\n", row);
666 ok(bits == (void *)0xdeadbeef, "Unepexpected data pointer %p\n", bits);
667
668 hr = pGetBufferedPaintBits(NULL, NULL, NULL);
669 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr);
670
671 hr = pGetBufferedPaintBits(NULL, &bits, NULL);
672 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr);
673
674 hr = pGetBufferedPaintBits(NULL, NULL, &row);
675 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr);
676
677 /* access buffer bits */
678 for (format = BPBF_COMPATIBLEBITMAP; format <= BPBF_TOPDOWNMONODIB; format++)
679 {
680 buffer = pBeginBufferedPaint(target, &rect, format, &params, &src);
681
682 /* only works for DIB buffers */
683 bits = NULL;
684 row = 0;
685 hr = pGetBufferedPaintBits(buffer, &bits, &row);
686 if (format == BPBF_COMPATIBLEBITMAP)
687 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr);
688 else
689 {
690 ok(hr == S_OK, "Unexpected return code %#x\n", hr);
691 ok(bits != NULL, "Bitmap bits %p\n", bits);
692 ok(row >= (rect.right - rect.left), "format %d: bitmap width %d\n", format, row);
693 }
694
695 hr = pEndBufferedPaint(buffer, FALSE);
696 ok(hr == S_OK, "Unexpected return code %#x\n", hr);
697 }
698
699 DeleteDC(target);
700 }
701
702 START_TEST(system)
703 {
704 init_funcs();
705
706 /* No real functional tests will be done (yet). The current tests
707 * only show input/return behaviour
708 */
709
710 /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
711 trace("Starting test_IsThemed()\n");
712 test_IsThemed();
713
714 /* GetWindowTheme */
715 trace("Starting test_GetWindowTheme()\n");
716 test_GetWindowTheme();
717
718 /* SetWindowTheme */
719 trace("Starting test_SetWindowTheme()\n");
720 test_SetWindowTheme();
721
722 /* OpenThemeData, a bit more functional now */
723 trace("Starting test_OpenThemeData()\n");
724 test_OpenThemeData();
725
726 /* OpenThemeDataEx */
727 trace("Starting test_OpenThemeDataEx()\n");
728 test_OpenThemeDataEx();
729
730 /* GetCurrentThemeName */
731 trace("Starting test_GetCurrentThemeName()\n");
732 test_GetCurrentThemeName();
733
734 /* CloseThemeData */
735 trace("Starting test_CloseThemeData()\n");
736 test_CloseThemeData();
737
738 test_buffered_paint();
739 }