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
26 #include "wine/test.h"
28 static HRESULT (WINAPI * pCloseThemeData)(HTHEME);
29 static HRESULT (WINAPI * pGetCurrentThemeName)(LPWSTR, int, LPWSTR, int, LPWSTR, int);
30 static HTHEME (WINAPI * pGetWindowTheme)(HWND);
31 static BOOL (WINAPI * pIsAppThemed)(VOID);
32 static BOOL (WINAPI * pIsThemeActive)(VOID);
33 static HTHEME (WINAPI * pOpenThemeData)(HWND, LPCWSTR);
34 static HRESULT (WINAPI * pSetWindowTheme)(HWND, LPCWSTR, LPCWSTR);
36 static HMODULE hUxtheme = 0;
38 #define UXTHEME_GET_PROC(func) \
39 p ## func = (void*)GetProcAddress(hUxtheme, #func); \
41 trace("GetProcAddress(%s) failed\n", #func); \
42 FreeLibrary(hUxtheme); \
46 static BOOL InitFunctionPtrs(void)
48 hUxtheme = LoadLibraryA("uxtheme.dll");
50 trace("Could not load uxtheme.dll\n");
55 UXTHEME_GET_PROC(CloseThemeData)
56 UXTHEME_GET_PROC(GetCurrentThemeName)
57 UXTHEME_GET_PROC(GetWindowTheme)
58 UXTHEME_GET_PROC(IsAppThemed)
59 UXTHEME_GET_PROC(IsThemeActive)
60 UXTHEME_GET_PROC(OpenThemeData)
61 UXTHEME_GET_PROC(SetWindowTheme)
63 /* The following functions should be available, if not return FALSE. The Vista functions will
64 * be checked (at some point in time) within the single tests if needed. All used functions for
65 * now are present on WinXP, W2K3 and Wine.
67 if (!pCloseThemeData || !pGetWindowTheme ||
68 !pIsAppThemed || !pIsThemeActive ||
69 !pOpenThemeData || !pSetWindowTheme ||
70 !pGetCurrentThemeName)
76 static void test_IsThemed(void)
81 SetLastError(0xdeadbeef);
82 bThemeActive = pIsThemeActive();
83 trace("Theming is %s\n", (bThemeActive) ? "active" : "inactive");
85 ok( GetLastError() == ERROR_SUCCESS,
86 "Expected ERROR_SUCCESS, got 0x%08lx\n",
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");
101 ok( GetLastError() == ERROR_SUCCESS,
102 "Expected ERROR_SUCCESS, got 0x%08lx\n",
106 static void test_GetWindowTheme(void)
112 SetLastError(0xdeadbeef);
113 hTheme = pGetWindowTheme(NULL);
114 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
116 ok( GetLastError() == E_HANDLE,
117 "Expected E_HANDLE, got 0x%08lx\n",
120 /* Only do the bare minumum to get a valid hwnd */
121 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
124 SetLastError(0xdeadbeef);
125 hTheme = pGetWindowTheme(hWnd);
126 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
127 ok( GetLastError() == 0xdeadbeef,
128 "Expected 0xdeadbeef, got 0x%08lx\n",
131 bDestroyed = DestroyWindow(hWnd);
133 trace("Window %p couldn't be destroyed : 0x%08lx\n",
134 hWnd, GetLastError());
137 static void test_SetWindowTheme(void)
143 SetLastError(0xdeadbeef);
144 hRes = pSetWindowTheme(NULL, NULL, NULL);
147 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08lx\n", hRes);
148 ok( GetLastError() == 0xdeadbeef,
149 "Expected 0xdeadbeef, got 0x%08lx\n",
153 /* Only do the bare minumum to get a valid hwnd */
154 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
157 SetLastError(0xdeadbeef);
158 hRes = pSetWindowTheme(hWnd, NULL, NULL);
159 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
160 ok( GetLastError() == 0xdeadbeef,
161 "Expected 0xdeadbeef, got 0x%08lx\n",
164 bDestroyed = DestroyWindow(hWnd);
166 trace("Window %p couldn't be destroyed : 0x%08lx\n",
167 hWnd, GetLastError());
170 static void test_OpenThemeData(void)
172 HTHEME hTheme, hTheme2;
178 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 };
179 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 };
180 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 };
181 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
183 bThemeActive = pIsThemeActive();
186 SetLastError(0xdeadbeef);
187 hTheme = pOpenThemeData(NULL, NULL);
188 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
190 ok( GetLastError() == E_POINTER,
191 "Expected GLE() to be E_POINTER, got 0x%08lx\n",
194 /* A NULL hWnd and an invalid classlist */
195 SetLastError(0xdeadbeef);
196 hTheme = pOpenThemeData(NULL, szInvalidClassList);
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%08lx\n",
203 SetLastError(0xdeadbeef);
204 hTheme = pOpenThemeData(NULL, szClassList);
207 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
209 ok( GetLastError() == ERROR_SUCCESS,
210 "Expected ERROR_SUCCESS, got 0x%08lx\n",
215 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
217 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
218 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
222 /* Only do the bare minumum to get a valid hdc */
223 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
226 SetLastError(0xdeadbeef);
227 hTheme = pOpenThemeData(hWnd, NULL);
228 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
230 ok( GetLastError() == E_POINTER,
231 "Expected GLE() to be E_POINTER, got 0x%08lx\n",
234 SetLastError(0xdeadbeef);
235 hTheme = pOpenThemeData(hWnd, szInvalidClassList);
236 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
238 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
239 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
244 SetLastError(0xdeadbeef);
245 hTheme = pOpenThemeData(hWnd, szButtonClassList);
246 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
248 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
249 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
251 trace("No active theme, skipping rest of OpenThemeData tests\n");
255 /* Only do the next checks if we have an active theme */
257 SetLastError(0xdeadbeef);
258 hTheme = pOpenThemeData(hWnd, szButtonClassList);
259 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
261 ok( GetLastError() == ERROR_SUCCESS,
262 "Expected ERROR_SUCCESS, got 0x%08lx\n",
265 /* Test with bUtToN instead of Button */
266 SetLastError(0xdeadbeef);
267 hTheme = pOpenThemeData(hWnd, szButtonClassList2);
268 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
270 ok( GetLastError() == ERROR_SUCCESS,
271 "Expected ERROR_SUCCESS, got 0x%08lx\n",
274 SetLastError(0xdeadbeef);
275 hTheme = pOpenThemeData(hWnd, szClassList);
276 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
278 ok( GetLastError() == ERROR_SUCCESS,
279 "Expected ERROR_SUCCESS, got 0x%08lx\n",
282 /* GetWindowTheme should return the last handle opened by OpenThemeData */
283 SetLastError(0xdeadbeef);
284 hTheme2 = pGetWindowTheme(hWnd);
285 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
287 ok( GetLastError() == 0xdeadbeef,
288 "Expected 0xdeadbeef, got 0x%08lx\n",
291 SetLastError(0xdeadbeef);
292 hRes = pCloseThemeData(hTheme);
293 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
294 ok( GetLastError() == 0xdeadbeef,
295 "Expected 0xdeadbeef, got 0x%08lx\n",
298 /* Close a second time */
299 SetLastError(0xdeadbeef);
300 hRes = pCloseThemeData(hTheme);
301 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
302 ok( GetLastError() == 0xdeadbeef,
303 "Expected 0xdeadbeef, got 0x%08lx\n",
306 /* See if closing makes a difference for GetWindowTheme */
307 SetLastError(0xdeadbeef);
309 hTheme2 = pGetWindowTheme(hWnd);
310 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
312 ok( GetLastError() == 0xdeadbeef,
313 "Expected 0xdeadbeef, got 0x%08lx\n",
316 bDestroyed = DestroyWindow(hWnd);
318 trace("Window %p couldn't be destroyed : 0x%08lx\n",
319 hWnd, GetLastError());
322 static void test_GetCurrentThemeName(void)
326 WCHAR currentTheme[MAX_PATH];
327 WCHAR currentColor[MAX_PATH];
328 WCHAR currentSize[MAX_PATH];
330 bThemeActive = pIsThemeActive();
333 SetLastError(0xdeadbeef);
334 hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
336 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
338 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
339 ok( GetLastError() == 0xdeadbeef,
340 "Expected 0xdeadbeef, got 0x%08lx\n",
343 /* Number of characters given is 0 */
344 SetLastError(0xdeadbeef);
345 hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
347 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
349 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
350 ok( GetLastError() == 0xdeadbeef,
351 "Expected 0xdeadbeef, got 0x%08lx\n",
354 /* When the number of characters given is too small (not 0, see above), GetCurrentThemeName returns 0x8007007a.
355 * The only definition I found was in strsafe.h:
357 * #define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
359 SetLastError(0xdeadbeef);
360 hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
363 ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08lx\n", hRes);
365 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
366 ok( GetLastError() == 0xdeadbeef,
367 "Expected 0xdeadbeef, got 0x%08lx\n",
370 /* The same is true if the number of characters is too small for Color and/or Size */
371 SetLastError(0xdeadbeef);
372 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
374 currentSize, sizeof(currentSize) / sizeof(WCHAR));
377 ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08lx\n", hRes);
379 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
380 ok( GetLastError() == 0xdeadbeef,
381 "Expected 0xdeadbeef, got 0x%08lx\n",
384 /* Given number of characters is correct */
385 SetLastError(0xdeadbeef);
386 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
388 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
390 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
391 ok( GetLastError() == 0xdeadbeef,
392 "Expected 0xdeadbeef, got 0x%08lx\n",
395 /* Given number of characters for the theme name is too large */
396 SetLastError(0xdeadbeef);
397 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0);
399 ok( hRes == E_POINTER, "Expected E_POINTER, got 0x%08lx\n", hRes);
400 ok( GetLastError() == 0xdeadbeef,
401 "Expected 0xdeadbeef, got 0x%08lx\n",
404 /* The too large case is only for the theme name, not for color name or size name */
405 SetLastError(0xdeadbeef);
406 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
407 currentColor, sizeof(currentTheme),
408 currentSize, sizeof(currentSize) / sizeof(WCHAR));
410 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
412 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
413 ok( GetLastError() == 0xdeadbeef,
414 "Expected 0xdeadbeef, got 0x%08lx\n",
417 SetLastError(0xdeadbeef);
418 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
419 currentColor, sizeof(currentTheme) / sizeof(WCHAR),
420 currentSize, sizeof(currentSize));
422 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
424 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
425 ok( GetLastError() == 0xdeadbeef,
426 "Expected 0xdeadbeef, got 0x%08lx\n",
430 SetLastError(0xdeadbeef);
431 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
432 currentColor, sizeof(currentColor) / sizeof(WCHAR),
433 currentSize, sizeof(currentSize) / sizeof(WCHAR));
435 ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
437 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08lx\n", hRes);
438 ok( GetLastError() == 0xdeadbeef,
439 "Expected 0xdeadbeef, got 0x%08lx\n",
443 static void test_CloseThemeData(void)
447 SetLastError(0xdeadbeef);
448 hRes = pCloseThemeData(NULL);
449 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08lx\n", hRes);
450 ok( GetLastError() == 0xdeadbeef,
451 "Expected 0xdeadbeef, got 0x%08lx\n",
457 if(!InitFunctionPtrs())
460 /* No real functional tests will be done (yet). The current tests
461 * only show input/return behaviour
464 /* IsThemeActive and IsAppThemed */
465 trace("Starting test_IsThemed()\n");
469 trace("Starting test_GetWindowTheme()\n");
470 test_GetWindowTheme();
473 trace("Starting test_SetWindowTheme()\n");
474 test_SetWindowTheme();
476 /* OpenThemeData, a bit more functional now */
477 trace("Starting test_OpenThemeData()\n");
478 test_OpenThemeData();
480 /* GetCurrentThemeName */
481 trace("Starting test_GetCurrentThemeName()\n");
482 test_GetCurrentThemeName();
485 trace("Starting test_CloseThemeData()\n");
486 test_CloseThemeData();
488 FreeLibrary(hUxtheme);