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");
88 ok( GetLastError() == ERROR_SUCCESS,
89 "Expected ERROR_SUCCESS, got 0x%08x\n",
92 /* This test is not themed */
93 SetLastError(0xdeadbeef);
94 bAppThemed = pIsAppThemed();
98 ok( bAppThemed == FALSE, "Expected FALSE as this test executable is not (yet) themed.\n");
100 /* Although Wine currently returns FALSE, the logic behind it is wrong. It is not a todo_wine though in the testing sense */
101 ok( bAppThemed == FALSE, "Expected FALSE as this test executable is not (yet) themed.\n");
103 ok( GetLastError() == ERROR_SUCCESS,
104 "Expected ERROR_SUCCESS, got 0x%08x\n",
107 SetLastError(0xdeadbeef);
108 bTPDefined = pIsThemePartDefined(NULL, 0 , 0);
109 ok( bTPDefined == FALSE, "Expected FALSE\n");
110 ok( GetLastError() == E_HANDLE,
111 "Expected E_HANDLE, got 0x%08x\n",
115 static void test_GetWindowTheme(void)
121 SetLastError(0xdeadbeef);
122 hTheme = pGetWindowTheme(NULL);
123 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
125 ok( GetLastError() == E_HANDLE,
126 "Expected E_HANDLE, got 0x%08x\n",
129 /* Only do the bare minimum to get a valid hwnd */
130 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
133 SetLastError(0xdeadbeef);
134 hTheme = pGetWindowTheme(hWnd);
135 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
136 ok( GetLastError() == 0xdeadbeef,
137 "Expected 0xdeadbeef, got 0x%08x\n",
140 bDestroyed = DestroyWindow(hWnd);
142 trace("Window %p couldn't be destroyed : 0x%08x\n",
143 hWnd, GetLastError());
146 static void test_SetWindowTheme(void)
152 SetLastError(0xdeadbeef);
153 hRes = pSetWindowTheme(NULL, NULL, NULL);
156 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
157 ok( GetLastError() == 0xdeadbeef,
158 "Expected 0xdeadbeef, got 0x%08x\n",
162 /* Only do the bare minimum to get a valid hwnd */
163 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
166 SetLastError(0xdeadbeef);
167 hRes = pSetWindowTheme(hWnd, NULL, NULL);
168 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
169 ok( GetLastError() == 0xdeadbeef,
170 "Expected 0xdeadbeef, got 0x%08x\n",
173 bDestroyed = DestroyWindow(hWnd);
175 trace("Window %p couldn't be destroyed : 0x%08x\n",
176 hWnd, GetLastError());
179 static void test_OpenThemeData(void)
181 HTHEME hTheme, hTheme2;
188 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 };
189 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 };
190 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 };
191 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
193 bThemeActive = pIsThemeActive();
196 SetLastError(0xdeadbeef);
197 hTheme = pOpenThemeData(NULL, NULL);
198 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
200 ok( GetLastError() == E_POINTER,
201 "Expected GLE() to be E_POINTER, got 0x%08x\n",
204 /* A NULL hWnd and an invalid classlist */
205 SetLastError(0xdeadbeef);
206 hTheme = pOpenThemeData(NULL, szInvalidClassList);
207 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
209 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
210 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
213 SetLastError(0xdeadbeef);
214 hTheme = pOpenThemeData(NULL, szClassList);
217 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
219 ok( GetLastError() == ERROR_SUCCESS,
220 "Expected ERROR_SUCCESS, got 0x%08x\n",
225 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
227 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
228 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
232 /* Only do the bare minimum to get a valid hdc */
233 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
236 SetLastError(0xdeadbeef);
237 hTheme = pOpenThemeData(hWnd, NULL);
238 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
240 ok( GetLastError() == E_POINTER,
241 "Expected GLE() to be E_POINTER, got 0x%08x\n",
244 SetLastError(0xdeadbeef);
245 hTheme = pOpenThemeData(hWnd, szInvalidClassList);
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%08x\n",
254 SetLastError(0xdeadbeef);
255 hTheme = pOpenThemeData(hWnd, szButtonClassList);
256 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
258 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
259 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
261 skip("No active theme, skipping rest of OpenThemeData tests\n");
265 /* Only do the next checks if we have an active theme */
267 SetLastError(0xdeadbeef);
268 hTheme = pOpenThemeData(hWnd, szButtonClassList);
269 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
271 ok( GetLastError() == ERROR_SUCCESS,
272 "Expected ERROR_SUCCESS, got 0x%08x\n",
275 /* Test with bUtToN instead of Button */
276 SetLastError(0xdeadbeef);
277 hTheme = pOpenThemeData(hWnd, szButtonClassList2);
278 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
280 ok( GetLastError() == ERROR_SUCCESS,
281 "Expected ERROR_SUCCESS, got 0x%08x\n",
284 SetLastError(0xdeadbeef);
285 hTheme = pOpenThemeData(hWnd, szClassList);
286 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
288 ok( GetLastError() == ERROR_SUCCESS,
289 "Expected ERROR_SUCCESS, got 0x%08x\n",
292 /* GetWindowTheme should return the last handle opened by OpenThemeData */
293 SetLastError(0xdeadbeef);
294 hTheme2 = pGetWindowTheme(hWnd);
295 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
297 ok( GetLastError() == 0xdeadbeef,
298 "Expected 0xdeadbeef, got 0x%08x\n",
301 SetLastError(0xdeadbeef);
302 hRes = pCloseThemeData(hTheme);
303 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
304 ok( GetLastError() == 0xdeadbeef,
305 "Expected 0xdeadbeef, got 0x%08x\n",
308 /* Close a second time */
309 SetLastError(0xdeadbeef);
310 hRes = pCloseThemeData(hTheme);
311 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
312 ok( GetLastError() == 0xdeadbeef,
313 "Expected 0xdeadbeef, got 0x%08x\n",
316 /* See if closing makes a difference for GetWindowTheme */
317 SetLastError(0xdeadbeef);
319 hTheme2 = pGetWindowTheme(hWnd);
320 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
322 ok( GetLastError() == 0xdeadbeef,
323 "Expected 0xdeadbeef, got 0x%08x\n",
326 SetLastError(0xdeadbeef);
327 bTPDefined = pIsThemePartDefined(hTheme, 0 , 0);
330 ok( bTPDefined == FALSE, "Expected FALSE\n");
331 ok( GetLastError() == ERROR_SUCCESS,
332 "Expected ERROR_SUCCESS, got 0x%08x\n",
336 bDestroyed = DestroyWindow(hWnd);
338 trace("Window %p couldn't be destroyed : 0x%08x\n",
339 hWnd, GetLastError());
342 static void test_GetCurrentThemeName(void)
346 WCHAR currentTheme[MAX_PATH];
347 WCHAR currentColor[MAX_PATH];
348 WCHAR currentSize[MAX_PATH];
350 bThemeActive = pIsThemeActive();
353 SetLastError(0xdeadbeef);
354 hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
356 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
358 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
359 ok( GetLastError() == 0xdeadbeef,
360 "Expected 0xdeadbeef, got 0x%08x\n",
363 /* Number of characters given is 0 */
364 SetLastError(0xdeadbeef);
365 hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
367 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
369 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
370 ok( GetLastError() == 0xdeadbeef,
371 "Expected 0xdeadbeef, got 0x%08x\n",
374 /* When the number of characters given is too small (not 0, see above), GetCurrentThemeName returns 0x8007007a.
375 * The only definition I found was in strsafe.h:
377 * #define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
379 SetLastError(0xdeadbeef);
380 hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
383 ok(hRes == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes);
385 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
386 ok( GetLastError() == 0xdeadbeef,
387 "Expected 0xdeadbeef, got 0x%08x\n",
390 /* The same is true if the number of characters is too small for Color and/or Size */
391 SetLastError(0xdeadbeef);
392 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
394 currentSize, sizeof(currentSize) / sizeof(WCHAR));
397 ok(hRes == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes);
399 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
400 ok( GetLastError() == 0xdeadbeef,
401 "Expected 0xdeadbeef, got 0x%08x\n",
404 /* Given number of characters is correct */
405 SetLastError(0xdeadbeef);
406 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
408 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
410 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
411 ok( GetLastError() == 0xdeadbeef,
412 "Expected 0xdeadbeef, got 0x%08x\n",
415 /* Given number of characters for the theme name is too large */
416 SetLastError(0xdeadbeef);
417 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0);
419 ok( hRes == E_POINTER || hRes == S_OK, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes);
421 ok( hRes == E_PROP_ID_UNSUPPORTED ||
422 hRes == E_POINTER, /* win2k3 */
423 "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
424 ok( GetLastError() == 0xdeadbeef,
425 "Expected 0xdeadbeef, got 0x%08x\n",
428 /* The too large case is only for the theme name, not for color name or size name */
429 SetLastError(0xdeadbeef);
430 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
431 currentColor, sizeof(currentTheme),
432 currentSize, sizeof(currentSize) / sizeof(WCHAR));
434 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
436 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
437 ok( GetLastError() == 0xdeadbeef,
438 "Expected 0xdeadbeef, got 0x%08x\n",
441 SetLastError(0xdeadbeef);
442 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
443 currentColor, sizeof(currentTheme) / sizeof(WCHAR),
444 currentSize, sizeof(currentSize));
446 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
448 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
449 ok( GetLastError() == 0xdeadbeef,
450 "Expected 0xdeadbeef, got 0x%08x\n",
454 SetLastError(0xdeadbeef);
455 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
456 currentColor, sizeof(currentColor) / sizeof(WCHAR),
457 currentSize, sizeof(currentSize) / sizeof(WCHAR));
459 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
461 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
462 ok( GetLastError() == 0xdeadbeef,
463 "Expected 0xdeadbeef, got 0x%08x\n",
467 static void test_CloseThemeData(void)
471 SetLastError(0xdeadbeef);
472 hRes = pCloseThemeData(NULL);
473 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
474 ok( GetLastError() == 0xdeadbeef,
475 "Expected 0xdeadbeef, got 0x%08x\n",
481 if(!InitFunctionPtrs())
484 /* No real functional tests will be done (yet). The current tests
485 * only show input/return behaviour
488 /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
489 trace("Starting test_IsThemed()\n");
493 trace("Starting test_GetWindowTheme()\n");
494 test_GetWindowTheme();
497 trace("Starting test_SetWindowTheme()\n");
498 test_SetWindowTheme();
500 /* OpenThemeData, a bit more functional now */
501 trace("Starting test_OpenThemeData()\n");
502 test_OpenThemeData();
504 /* GetCurrentThemeName */
505 trace("Starting test_GetCurrentThemeName()\n");
506 test_GetCurrentThemeName();
509 trace("Starting test_CloseThemeData()\n");
510 test_CloseThemeData();
512 FreeLibrary(hUxtheme);