1 /* Unit test suite for uxtheme API functions
3 * Copyright 2006 Paul Vriens
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.
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.
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
27 #include "wine/test.h"
29 static HRESULT (WINAPI
* pCloseThemeData
)(HTHEME
);
30 static HRESULT (WINAPI
* pGetCurrentThemeName
)(LPWSTR
, int, LPWSTR
, int, LPWSTR
, int);
31 static HTHEME (WINAPI
* pGetWindowTheme
)(HWND
);
32 static BOOL (WINAPI
* pIsAppThemed
)(VOID
);
33 static BOOL (WINAPI
* pIsThemeActive
)(VOID
);
34 static BOOL (WINAPI
* pIsThemePartDefined
)(HTHEME
, int, int);
35 static HTHEME (WINAPI
* pOpenThemeData
)(HWND
, LPCWSTR
);
36 static HTHEME (WINAPI
* pOpenThemeDataEx
)(HWND
, LPCWSTR
, DWORD
);
37 static HRESULT (WINAPI
* pSetWindowTheme
)(HWND
, LPCWSTR
, LPCWSTR
);
39 static HMODULE hUxtheme
= 0;
41 #define UXTHEME_GET_PROC(func) p ## func = (void*)GetProcAddress(hUxtheme, #func);
43 static BOOL
InitFunctionPtrs(void)
45 hUxtheme
= LoadLibraryA("uxtheme.dll");
47 trace("Could not load uxtheme.dll\n");
52 UXTHEME_GET_PROC(CloseThemeData
)
53 UXTHEME_GET_PROC(GetCurrentThemeName
)
54 UXTHEME_GET_PROC(GetWindowTheme
)
55 UXTHEME_GET_PROC(IsAppThemed
)
56 UXTHEME_GET_PROC(IsThemeActive
)
57 UXTHEME_GET_PROC(IsThemePartDefined
)
58 UXTHEME_GET_PROC(OpenThemeData
)
59 UXTHEME_GET_PROC(OpenThemeDataEx
)
60 UXTHEME_GET_PROC(SetWindowTheme
)
62 /* The following functions should be available, if not return FALSE. The Vista functions will
63 * be checked (at some point in time) within the single tests if needed. All used functions for
64 * now are present on WinXP, W2K3 and Wine.
66 if (!pCloseThemeData
|| !pGetCurrentThemeName
||
67 !pGetWindowTheme
|| !pIsAppThemed
||
68 !pIsThemeActive
|| !pIsThemePartDefined
||
69 !pOpenThemeData
|| !pSetWindowTheme
)
71 FreeLibrary(hUxtheme
);
78 static void test_IsThemed(void)
84 bThemeActive
= pIsThemeActive();
85 trace("Theming is %s\n", (bThemeActive
) ? "active" : "inactive");
87 bAppThemed
= pIsAppThemed();
88 trace("Test executable is %s\n", (bAppThemed
) ? "themed" : "not themed");
90 SetLastError(0xdeadbeef);
91 bTPDefined
= pIsThemePartDefined(NULL
, 0 , 0);
92 ok( bTPDefined
== FALSE
, "Expected FALSE\n");
93 ok( GetLastError() == E_HANDLE
,
94 "Expected E_HANDLE, got 0x%08x\n",
98 static void test_GetWindowTheme(void)
104 SetLastError(0xdeadbeef);
105 hTheme
= pGetWindowTheme(NULL
);
106 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
108 ok( GetLastError() == E_HANDLE
,
109 "Expected E_HANDLE, got 0x%08x\n",
112 /* Only do the bare minimum to get a valid hwnd */
113 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
116 SetLastError(0xdeadbeef);
117 hTheme
= pGetWindowTheme(hWnd
);
118 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
119 ok( GetLastError() == 0xdeadbeef,
120 "Expected 0xdeadbeef, got 0x%08x\n",
123 bDestroyed
= DestroyWindow(hWnd
);
125 trace("Window %p couldn't be destroyed : 0x%08x\n",
126 hWnd
, GetLastError());
129 static void test_SetWindowTheme(void)
135 hRes
= pSetWindowTheme(NULL
, NULL
, NULL
);
137 ok( hRes
== E_HANDLE
, "Expected E_HANDLE, got 0x%08x\n", hRes
);
139 /* Only do the bare minimum to get a valid hwnd */
140 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
143 hRes
= pSetWindowTheme(hWnd
, NULL
, NULL
);
144 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
146 bDestroyed
= DestroyWindow(hWnd
);
148 trace("Window %p couldn't be destroyed : 0x%08x\n",
149 hWnd
, GetLastError());
152 static void test_OpenThemeData(void)
154 HTHEME hTheme
, hTheme2
;
161 WCHAR szInvalidClassList
[] = {'D','E','A','D','B','E','E','F', 0 };
162 WCHAR szButtonClassList
[] = {'B','u','t','t','o','n', 0 };
163 WCHAR szButtonClassList2
[] = {'b','U','t','T','o','N', 0 };
164 WCHAR szClassList
[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
166 bThemeActive
= pIsThemeActive();
169 SetLastError(0xdeadbeef);
170 hTheme
= pOpenThemeData(NULL
, NULL
);
171 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
172 ok( GetLastError() == E_POINTER
,
173 "Expected GLE() to be E_POINTER, got 0x%08x\n",
176 /* A NULL hWnd and an invalid classlist */
177 SetLastError(0xdeadbeef);
178 hTheme
= pOpenThemeData(NULL
, szInvalidClassList
);
179 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
181 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
182 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
185 SetLastError(0xdeadbeef);
186 hTheme
= pOpenThemeData(NULL
, szClassList
);
189 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
191 ok( GetLastError() == ERROR_SUCCESS
,
192 "Expected ERROR_SUCCESS, got 0x%08x\n",
197 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
199 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
200 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
204 /* Only do the bare minimum to get a valid hdc */
205 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
208 SetLastError(0xdeadbeef);
209 hTheme
= pOpenThemeData(hWnd
, NULL
);
210 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
211 ok( GetLastError() == E_POINTER
,
212 "Expected GLE() to be E_POINTER, got 0x%08x\n",
215 SetLastError(0xdeadbeef);
216 hTheme
= pOpenThemeData(hWnd
, szInvalidClassList
);
217 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
219 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
220 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
225 SetLastError(0xdeadbeef);
226 hTheme
= pOpenThemeData(hWnd
, szButtonClassList
);
227 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
229 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
230 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
232 skip("No active theme, skipping rest of OpenThemeData tests\n");
236 /* Only do the next checks if we have an active theme */
238 SetLastError(0xdeadbeef);
239 hTheme
= pOpenThemeData(hWnd
, szButtonClassList
);
240 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
242 ok( GetLastError() == ERROR_SUCCESS
,
243 "Expected ERROR_SUCCESS, got 0x%08x\n",
246 /* Test with bUtToN instead of Button */
247 SetLastError(0xdeadbeef);
248 hTheme
= pOpenThemeData(hWnd
, szButtonClassList2
);
249 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
251 ok( GetLastError() == ERROR_SUCCESS
,
252 "Expected ERROR_SUCCESS, got 0x%08x\n",
255 SetLastError(0xdeadbeef);
256 hTheme
= pOpenThemeData(hWnd
, szClassList
);
257 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
259 ok( GetLastError() == ERROR_SUCCESS
,
260 "Expected ERROR_SUCCESS, got 0x%08x\n",
263 /* GetWindowTheme should return the last handle opened by OpenThemeData */
264 SetLastError(0xdeadbeef);
265 hTheme2
= pGetWindowTheme(hWnd
);
266 ok( hTheme
== hTheme2
, "Expected the same HTHEME handle (%p<->%p)\n",
268 ok( GetLastError() == 0xdeadbeef,
269 "Expected 0xdeadbeef, got 0x%08x\n",
272 hRes
= pCloseThemeData(hTheme
);
273 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
275 /* Close a second time */
276 hRes
= pCloseThemeData(hTheme
);
277 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
279 /* See if closing makes a difference for GetWindowTheme */
280 SetLastError(0xdeadbeef);
282 hTheme2
= pGetWindowTheme(hWnd
);
283 ok( hTheme
== hTheme2
, "Expected the same HTHEME handle (%p<->%p)\n",
285 ok( GetLastError() == 0xdeadbeef,
286 "Expected 0xdeadbeef, got 0x%08x\n",
289 SetLastError(0xdeadbeef);
290 bTPDefined
= pIsThemePartDefined(hTheme
, 0 , 0);
293 ok( bTPDefined
== FALSE
, "Expected FALSE\n");
294 ok( GetLastError() == ERROR_SUCCESS
,
295 "Expected ERROR_SUCCESS, got 0x%08x\n",
299 bDestroyed
= DestroyWindow(hWnd
);
301 trace("Window %p couldn't be destroyed : 0x%08x\n",
302 hWnd
, GetLastError());
305 static void test_OpenThemeDataEx(void)
312 WCHAR szInvalidClassList
[] = {'D','E','A','D','B','E','E','F', 0 };
313 WCHAR szButtonClassList
[] = {'B','u','t','t','o','n', 0 };
314 WCHAR szButtonClassList2
[] = {'b','U','t','T','o','N', 0 };
315 WCHAR szClassList
[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
317 if (!pOpenThemeDataEx
)
319 win_skip("OpenThemeDataEx not available\n");
323 bThemeActive
= pIsThemeActive();
326 SetLastError(0xdeadbeef);
327 hTheme
= pOpenThemeDataEx(NULL
, NULL
, 0);
328 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
329 ok( GetLastError() == E_POINTER
,
330 "Expected GLE() to be E_POINTER, got 0x%08x\n",
333 /* A NULL hWnd and an invalid classlist without flags */
334 SetLastError(0xdeadbeef);
335 hTheme
= pOpenThemeDataEx(NULL
, szInvalidClassList
, 0);
336 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
338 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
339 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
342 SetLastError(0xdeadbeef);
343 hTheme
= pOpenThemeDataEx(NULL
, szClassList
, 0);
346 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
348 ok( GetLastError() == ERROR_SUCCESS
,
349 "Expected ERROR_SUCCESS, got 0x%08x\n",
354 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
356 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
357 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
361 /* Only do the bare minimum to get a valid hdc */
362 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
365 SetLastError(0xdeadbeef);
366 hTheme
= pOpenThemeDataEx(hWnd
, NULL
, 0);
367 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
368 ok( GetLastError() == E_POINTER
,
369 "Expected GLE() to be E_POINTER, got 0x%08x\n",
372 SetLastError(0xdeadbeef);
373 hTheme
= pOpenThemeDataEx(hWnd
, szInvalidClassList
, 0);
374 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
376 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
377 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
382 SetLastError(0xdeadbeef);
383 hTheme
= pOpenThemeDataEx(hWnd
, szButtonClassList
, 0);
384 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
386 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
387 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
389 skip("No active theme, skipping rest of OpenThemeDataEx tests\n");
393 /* Only do the next checks if we have an active theme */
395 SetLastError(0xdeadbeef);
396 hTheme
= pOpenThemeDataEx(hWnd
, szButtonClassList
, 0);
397 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
399 ok( GetLastError() == ERROR_SUCCESS
,
400 "Expected ERROR_SUCCESS, got 0x%08x\n",
403 SetLastError(0xdeadbeef);
404 hTheme
= pOpenThemeDataEx(hWnd
, szButtonClassList
, OTD_FORCE_RECT_SIZING
);
405 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
407 ok( GetLastError() == ERROR_SUCCESS
,
408 "Expected ERROR_SUCCESS, got 0x%08x\n",
411 SetLastError(0xdeadbeef);
412 hTheme
= pOpenThemeDataEx(hWnd
, szButtonClassList
, OTD_NONCLIENT
);
413 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
415 ok( GetLastError() == ERROR_SUCCESS
,
416 "Expected ERROR_SUCCESS, got 0x%08x\n",
419 SetLastError(0xdeadbeef);
420 hTheme
= pOpenThemeDataEx(hWnd
, szButtonClassList
, 0x3);
421 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
423 ok( GetLastError() == ERROR_SUCCESS
,
424 "Expected ERROR_SUCCESS, got 0x%08x\n",
427 /* Test with bUtToN instead of Button */
428 SetLastError(0xdeadbeef);
429 hTheme
= pOpenThemeDataEx(hWnd
, szButtonClassList2
, 0);
430 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
432 ok( GetLastError() == ERROR_SUCCESS
,
433 "Expected ERROR_SUCCESS, got 0x%08x\n",
436 SetLastError(0xdeadbeef);
437 hTheme
= pOpenThemeDataEx(hWnd
, szClassList
, 0);
438 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
440 ok( GetLastError() == ERROR_SUCCESS
,
441 "Expected ERROR_SUCCESS, got 0x%08x\n",
444 bDestroyed
= DestroyWindow(hWnd
);
446 trace("Window %p couldn't be destroyed : 0x%08x\n",
447 hWnd
, GetLastError());
450 static void test_GetCurrentThemeName(void)
454 WCHAR currentTheme
[MAX_PATH
];
455 WCHAR currentColor
[MAX_PATH
];
456 WCHAR currentSize
[MAX_PATH
];
458 bThemeActive
= pIsThemeActive();
461 hRes
= pGetCurrentThemeName(NULL
, 0, NULL
, 0, NULL
, 0);
463 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
465 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
467 /* Number of characters given is 0 */
468 hRes
= pGetCurrentThemeName(currentTheme
, 0, NULL
, 0, NULL
, 0);
470 ok( hRes
== S_OK
|| broken(hRes
== E_FAIL
/* WinXP SP1 */), "Expected S_OK, got 0x%08x\n", hRes
);
472 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
474 hRes
= pGetCurrentThemeName(currentTheme
, 2, NULL
, 0, NULL
, 0);
477 ok(hRes
== E_NOT_SUFFICIENT_BUFFER
||
478 broken(hRes
== E_FAIL
/* WinXP SP1 */),
479 "Expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hRes
);
481 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
483 /* The same is true if the number of characters is too small for Color and/or Size */
484 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
486 currentSize
, sizeof(currentSize
) / sizeof(WCHAR
));
489 ok(hRes
== E_NOT_SUFFICIENT_BUFFER
||
490 broken(hRes
== E_FAIL
/* WinXP SP1 */),
491 "Expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hRes
);
493 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
495 /* Given number of characters is correct */
496 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
), NULL
, 0, NULL
, 0);
498 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
500 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
502 /* Given number of characters for the theme name is too large */
503 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
), NULL
, 0, NULL
, 0);
505 ok( hRes
== E_POINTER
|| hRes
== S_OK
, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes
);
507 ok( hRes
== E_PROP_ID_UNSUPPORTED
||
508 hRes
== E_POINTER
, /* win2k3 */
509 "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
511 /* The too large case is only for the theme name, not for color name or size name */
512 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
513 currentColor
, sizeof(currentTheme
),
514 currentSize
, sizeof(currentSize
) / sizeof(WCHAR
));
516 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
518 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
520 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
521 currentColor
, sizeof(currentTheme
) / sizeof(WCHAR
),
522 currentSize
, sizeof(currentSize
));
524 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
526 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
529 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
530 currentColor
, sizeof(currentColor
) / sizeof(WCHAR
),
531 currentSize
, sizeof(currentSize
) / sizeof(WCHAR
));
533 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
535 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
538 static void test_CloseThemeData(void)
542 hRes
= pCloseThemeData(NULL
);
543 ok( hRes
== E_HANDLE
, "Expected E_HANDLE, got 0x%08x\n", hRes
);
548 if(!InitFunctionPtrs())
551 /* No real functional tests will be done (yet). The current tests
552 * only show input/return behaviour
555 /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
556 trace("Starting test_IsThemed()\n");
560 trace("Starting test_GetWindowTheme()\n");
561 test_GetWindowTheme();
564 trace("Starting test_SetWindowTheme()\n");
565 test_SetWindowTheme();
567 /* OpenThemeData, a bit more functional now */
568 trace("Starting test_OpenThemeData()\n");
569 test_OpenThemeData();
571 /* OpenThemeDataEx */
572 trace("Starting test_OpenThemeDataEx()\n");
573 test_OpenThemeDataEx();
575 /* GetCurrentThemeName */
576 trace("Starting test_GetCurrentThemeName()\n");
577 test_GetCurrentThemeName();
580 trace("Starting test_CloseThemeData()\n");
581 test_CloseThemeData();
583 FreeLibrary(hUxtheme
);