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 HRESULT (WINAPI
* pSetWindowTheme
)(HWND
, LPCWSTR
, LPCWSTR
);
38 static HMODULE hUxtheme
= 0;
40 #define UXTHEME_GET_PROC(func) \
41 p ## func = (void*)GetProcAddress(hUxtheme, #func); \
43 trace("GetProcAddress(%s) failed\n", #func); \
44 FreeLibrary(hUxtheme); \
48 static BOOL
InitFunctionPtrs(void)
50 hUxtheme
= LoadLibraryA("uxtheme.dll");
52 trace("Could not load uxtheme.dll\n");
57 UXTHEME_GET_PROC(CloseThemeData
)
58 UXTHEME_GET_PROC(GetCurrentThemeName
)
59 UXTHEME_GET_PROC(GetWindowTheme
)
60 UXTHEME_GET_PROC(IsAppThemed
)
61 UXTHEME_GET_PROC(IsThemeActive
)
62 UXTHEME_GET_PROC(IsThemePartDefined
)
63 UXTHEME_GET_PROC(OpenThemeData
)
64 UXTHEME_GET_PROC(SetWindowTheme
)
66 /* The following functions should be available, if not return FALSE. The Vista functions will
67 * be checked (at some point in time) within the single tests if needed. All used functions for
68 * now are present on WinXP, W2K3 and Wine.
70 if (!pCloseThemeData
|| !pGetCurrentThemeName
||
71 !pGetWindowTheme
|| !pIsAppThemed
||
72 !pIsThemeActive
|| !pIsThemePartDefined
||
73 !pOpenThemeData
|| !pSetWindowTheme
)
79 static void test_IsThemed(void)
85 SetLastError(0xdeadbeef);
86 bThemeActive
= pIsThemeActive();
87 trace("Theming is %s\n", (bThemeActive
) ? "active" : "inactive");
89 /* This test is not themed */
90 SetLastError(0xdeadbeef);
91 bAppThemed
= pIsAppThemed();
95 ok( bAppThemed
== FALSE
, "Expected FALSE as this test executable is not (yet) themed.\n");
97 /* Although Wine currently returns FALSE, the logic behind it is wrong. It is not a todo_wine though in the testing sense */
98 ok( bAppThemed
== FALSE
, "Expected FALSE as this test executable is not (yet) themed.\n");
100 ok( GetLastError() == ERROR_SUCCESS
,
101 "Expected ERROR_SUCCESS, got 0x%08x\n",
104 SetLastError(0xdeadbeef);
105 bTPDefined
= pIsThemePartDefined(NULL
, 0 , 0);
106 ok( bTPDefined
== FALSE
, "Expected FALSE\n");
107 ok( GetLastError() == E_HANDLE
,
108 "Expected E_HANDLE, got 0x%08x\n",
112 static void test_GetWindowTheme(void)
118 SetLastError(0xdeadbeef);
119 hTheme
= pGetWindowTheme(NULL
);
120 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
122 ok( GetLastError() == E_HANDLE
,
123 "Expected E_HANDLE, got 0x%08x\n",
126 /* Only do the bare minimum to get a valid hwnd */
127 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
130 SetLastError(0xdeadbeef);
131 hTheme
= pGetWindowTheme(hWnd
);
132 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
133 ok( GetLastError() == 0xdeadbeef,
134 "Expected 0xdeadbeef, got 0x%08x\n",
137 bDestroyed
= DestroyWindow(hWnd
);
139 trace("Window %p couldn't be destroyed : 0x%08x\n",
140 hWnd
, GetLastError());
143 static void test_SetWindowTheme(void)
149 SetLastError(0xdeadbeef);
150 hRes
= pSetWindowTheme(NULL
, NULL
, NULL
);
153 ok( hRes
== E_HANDLE
, "Expected E_HANDLE, got 0x%08x\n", hRes
);
154 ok( GetLastError() == 0xdeadbeef,
155 "Expected 0xdeadbeef, got 0x%08x\n",
159 /* Only do the bare minimum to get a valid hwnd */
160 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
163 SetLastError(0xdeadbeef);
164 hRes
= pSetWindowTheme(hWnd
, NULL
, NULL
);
165 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
166 ok( GetLastError() == 0xdeadbeef,
167 "Expected 0xdeadbeef, got 0x%08x\n",
170 bDestroyed
= DestroyWindow(hWnd
);
172 trace("Window %p couldn't be destroyed : 0x%08x\n",
173 hWnd
, GetLastError());
176 static void test_OpenThemeData(void)
178 HTHEME hTheme
, hTheme2
;
185 WCHAR szInvalidClassList
[] = {'D','E','A','D','B','E','E','F', 0 };
186 WCHAR szButtonClassList
[] = {'B','u','t','t','o','n', 0 };
187 WCHAR szButtonClassList2
[] = {'b','U','t','T','o','N', 0 };
188 WCHAR szClassList
[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
190 bThemeActive
= pIsThemeActive();
193 SetLastError(0xdeadbeef);
194 hTheme
= pOpenThemeData(NULL
, NULL
);
195 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
197 ok( GetLastError() == E_POINTER
,
198 "Expected GLE() to be E_POINTER, got 0x%08x\n",
201 /* A NULL hWnd and an invalid classlist */
202 SetLastError(0xdeadbeef);
203 hTheme
= pOpenThemeData(NULL
, szInvalidClassList
);
204 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
206 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
207 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
210 SetLastError(0xdeadbeef);
211 hTheme
= pOpenThemeData(NULL
, szClassList
);
214 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
216 ok( GetLastError() == ERROR_SUCCESS
,
217 "Expected ERROR_SUCCESS, got 0x%08x\n",
222 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
224 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
225 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
229 /* Only do the bare minimum to get a valid hdc */
230 hWnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,0, 0, 0, NULL
);
233 SetLastError(0xdeadbeef);
234 hTheme
= pOpenThemeData(hWnd
, NULL
);
235 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
237 ok( GetLastError() == E_POINTER
,
238 "Expected GLE() to be E_POINTER, got 0x%08x\n",
241 SetLastError(0xdeadbeef);
242 hTheme
= pOpenThemeData(hWnd
, szInvalidClassList
);
243 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
245 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
246 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
251 SetLastError(0xdeadbeef);
252 hTheme
= pOpenThemeData(hWnd
, szButtonClassList
);
253 ok( hTheme
== NULL
, "Expected a NULL return, got %p\n", hTheme
);
255 ok( GetLastError() == E_PROP_ID_UNSUPPORTED
,
256 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
258 skip("No active theme, skipping rest of OpenThemeData tests\n");
262 /* Only do the next checks if we have an active theme */
264 SetLastError(0xdeadbeef);
265 hTheme
= pOpenThemeData(hWnd
, szButtonClassList
);
266 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
268 ok( GetLastError() == ERROR_SUCCESS
,
269 "Expected ERROR_SUCCESS, got 0x%08x\n",
272 /* Test with bUtToN instead of Button */
273 SetLastError(0xdeadbeef);
274 hTheme
= pOpenThemeData(hWnd
, szButtonClassList2
);
275 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
277 ok( GetLastError() == ERROR_SUCCESS
,
278 "Expected ERROR_SUCCESS, got 0x%08x\n",
281 SetLastError(0xdeadbeef);
282 hTheme
= pOpenThemeData(hWnd
, szClassList
);
283 ok( hTheme
!= NULL
, "got NULL, expected a HTHEME handle\n");
285 ok( GetLastError() == ERROR_SUCCESS
,
286 "Expected ERROR_SUCCESS, got 0x%08x\n",
289 /* GetWindowTheme should return the last handle opened by OpenThemeData */
290 SetLastError(0xdeadbeef);
291 hTheme2
= pGetWindowTheme(hWnd
);
292 ok( hTheme
== hTheme2
, "Expected the same HTHEME handle (%p<->%p)\n",
294 ok( GetLastError() == 0xdeadbeef,
295 "Expected 0xdeadbeef, got 0x%08x\n",
298 SetLastError(0xdeadbeef);
299 hRes
= pCloseThemeData(hTheme
);
300 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
301 ok( GetLastError() == 0xdeadbeef,
302 "Expected 0xdeadbeef, got 0x%08x\n",
305 /* Close a second time */
306 SetLastError(0xdeadbeef);
307 hRes
= pCloseThemeData(hTheme
);
308 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
309 ok( GetLastError() == 0xdeadbeef,
310 "Expected 0xdeadbeef, got 0x%08x\n",
313 /* See if closing makes a difference for GetWindowTheme */
314 SetLastError(0xdeadbeef);
316 hTheme2
= pGetWindowTheme(hWnd
);
317 ok( hTheme
== hTheme2
, "Expected the same HTHEME handle (%p<->%p)\n",
319 ok( GetLastError() == 0xdeadbeef,
320 "Expected 0xdeadbeef, got 0x%08x\n",
323 SetLastError(0xdeadbeef);
324 bTPDefined
= pIsThemePartDefined(hTheme
, 0 , 0);
327 ok( bTPDefined
== FALSE
, "Expected FALSE\n");
328 ok( GetLastError() == ERROR_SUCCESS
,
329 "Expected ERROR_SUCCESS, got 0x%08x\n",
333 bDestroyed
= DestroyWindow(hWnd
);
335 trace("Window %p couldn't be destroyed : 0x%08x\n",
336 hWnd
, GetLastError());
339 static void test_GetCurrentThemeName(void)
343 WCHAR currentTheme
[MAX_PATH
];
344 WCHAR currentColor
[MAX_PATH
];
345 WCHAR currentSize
[MAX_PATH
];
347 bThemeActive
= pIsThemeActive();
350 SetLastError(0xdeadbeef);
351 hRes
= pGetCurrentThemeName(NULL
, 0, NULL
, 0, NULL
, 0);
353 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
355 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
356 ok( GetLastError() == 0xdeadbeef,
357 "Expected 0xdeadbeef, got 0x%08x\n",
360 /* Number of characters given is 0 */
361 SetLastError(0xdeadbeef);
362 hRes
= pGetCurrentThemeName(currentTheme
, 0, NULL
, 0, NULL
, 0);
364 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
366 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
367 ok( GetLastError() == 0xdeadbeef,
368 "Expected 0xdeadbeef, got 0x%08x\n",
371 /* When the number of characters given is too small (not 0, see above), GetCurrentThemeName returns 0x8007007a.
372 * The only definition I found was in strsafe.h:
374 * #define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
376 SetLastError(0xdeadbeef);
377 hRes
= pGetCurrentThemeName(currentTheme
, 2, NULL
, 0, NULL
, 0);
380 ok(hRes
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes
);
382 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
383 ok( GetLastError() == 0xdeadbeef,
384 "Expected 0xdeadbeef, got 0x%08x\n",
387 /* The same is true if the number of characters is too small for Color and/or Size */
388 SetLastError(0xdeadbeef);
389 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
391 currentSize
, sizeof(currentSize
) / sizeof(WCHAR
));
394 ok(hRes
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes
);
396 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
397 ok( GetLastError() == 0xdeadbeef,
398 "Expected 0xdeadbeef, got 0x%08x\n",
401 /* Given number of characters is correct */
402 SetLastError(0xdeadbeef);
403 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
), NULL
, 0, NULL
, 0);
405 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
407 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
408 ok( GetLastError() == 0xdeadbeef,
409 "Expected 0xdeadbeef, got 0x%08x\n",
412 /* Given number of characters for the theme name is too large */
413 SetLastError(0xdeadbeef);
414 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
), NULL
, 0, NULL
, 0);
416 ok( hRes
== E_POINTER
|| hRes
== S_OK
, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes
);
418 ok( hRes
== E_PROP_ID_UNSUPPORTED
||
419 hRes
== E_POINTER
, /* win2k3 */
420 "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
421 ok( GetLastError() == 0xdeadbeef,
422 "Expected 0xdeadbeef, got 0x%08x\n",
425 /* The too large case is only for the theme name, not for color name or size name */
426 SetLastError(0xdeadbeef);
427 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
428 currentColor
, sizeof(currentTheme
),
429 currentSize
, sizeof(currentSize
) / sizeof(WCHAR
));
431 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
433 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
434 ok( GetLastError() == 0xdeadbeef,
435 "Expected 0xdeadbeef, got 0x%08x\n",
438 SetLastError(0xdeadbeef);
439 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
440 currentColor
, sizeof(currentTheme
) / sizeof(WCHAR
),
441 currentSize
, sizeof(currentSize
));
443 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
445 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
446 ok( GetLastError() == 0xdeadbeef,
447 "Expected 0xdeadbeef, got 0x%08x\n",
451 SetLastError(0xdeadbeef);
452 hRes
= pGetCurrentThemeName(currentTheme
, sizeof(currentTheme
) / sizeof(WCHAR
),
453 currentColor
, sizeof(currentColor
) / sizeof(WCHAR
),
454 currentSize
, sizeof(currentSize
) / sizeof(WCHAR
));
456 ok( hRes
== S_OK
, "Expected S_OK, got 0x%08x\n", hRes
);
458 ok( hRes
== E_PROP_ID_UNSUPPORTED
, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes
);
459 ok( GetLastError() == 0xdeadbeef,
460 "Expected 0xdeadbeef, got 0x%08x\n",
464 static void test_CloseThemeData(void)
468 SetLastError(0xdeadbeef);
469 hRes
= pCloseThemeData(NULL
);
470 ok( hRes
== E_HANDLE
, "Expected E_HANDLE, got 0x%08x\n", hRes
);
471 ok( GetLastError() == 0xdeadbeef,
472 "Expected 0xdeadbeef, got 0x%08x\n",
478 if(!InitFunctionPtrs())
481 /* No real functional tests will be done (yet). The current tests
482 * only show input/return behaviour
485 /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
486 trace("Starting test_IsThemed()\n");
490 trace("Starting test_GetWindowTheme()\n");
491 test_GetWindowTheme();
494 trace("Starting test_SetWindowTheme()\n");
495 test_SetWindowTheme();
497 /* OpenThemeData, a bit more functional now */
498 trace("Starting test_OpenThemeData()\n");
499 test_OpenThemeData();
501 /* GetCurrentThemeName */
502 trace("Starting test_GetCurrentThemeName()\n");
503 test_GetCurrentThemeName();
506 trace("Starting test_CloseThemeData()\n");
507 test_CloseThemeData();
509 FreeLibrary(hUxtheme
);