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 BOOL (WINAPI * pIsThemePartDefined)(HTHEME, int, int);
34 static HTHEME (WINAPI * pOpenThemeData)(HWND, LPCWSTR);
35 static HRESULT (WINAPI * pSetWindowTheme)(HWND, LPCWSTR, LPCWSTR);
37 static HMODULE hUxtheme = 0;
39 #define UXTHEME_GET_PROC(func) \
40 p ## func = (void*)GetProcAddress(hUxtheme, #func); \
42 trace("GetProcAddress(%s) failed\n", #func); \
43 FreeLibrary(hUxtheme); \
47 static BOOL InitFunctionPtrs(void)
49 hUxtheme = LoadLibraryA("uxtheme.dll");
51 trace("Could not load uxtheme.dll\n");
56 UXTHEME_GET_PROC(CloseThemeData)
57 UXTHEME_GET_PROC(GetCurrentThemeName)
58 UXTHEME_GET_PROC(GetWindowTheme)
59 UXTHEME_GET_PROC(IsAppThemed)
60 UXTHEME_GET_PROC(IsThemeActive)
61 UXTHEME_GET_PROC(IsThemePartDefined)
62 UXTHEME_GET_PROC(OpenThemeData)
63 UXTHEME_GET_PROC(SetWindowTheme)
65 /* The following functions should be available, if not return FALSE. The Vista functions will
66 * be checked (at some point in time) within the single tests if needed. All used functions for
67 * now are present on WinXP, W2K3 and Wine.
69 if (!pCloseThemeData || !pGetCurrentThemeName ||
70 !pGetWindowTheme || !pIsAppThemed ||
71 !pIsThemeActive || !pIsThemePartDefined ||
72 !pOpenThemeData || !pSetWindowTheme)
78 static void test_IsThemed(void)
84 SetLastError(0xdeadbeef);
85 bThemeActive = pIsThemeActive();
86 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");
104 ok( GetLastError() == ERROR_SUCCESS,
105 "Expected ERROR_SUCCESS, got 0x%08x\n",
108 SetLastError(0xdeadbeef);
109 bTPDefined = pIsThemePartDefined(NULL, 0 , 0);
110 ok( bTPDefined == FALSE, "Expected FALSE\n");
111 ok( GetLastError() == E_HANDLE,
112 "Expected E_HANDLE, got 0x%08x\n",
116 static void test_GetWindowTheme(void)
122 SetLastError(0xdeadbeef);
123 hTheme = pGetWindowTheme(NULL);
124 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
126 ok( GetLastError() == E_HANDLE,
127 "Expected E_HANDLE, got 0x%08x\n",
130 /* Only do the bare minumum to get a valid hwnd */
131 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
134 SetLastError(0xdeadbeef);
135 hTheme = pGetWindowTheme(hWnd);
136 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
137 ok( GetLastError() == 0xdeadbeef,
138 "Expected 0xdeadbeef, got 0x%08x\n",
141 bDestroyed = DestroyWindow(hWnd);
143 trace("Window %p couldn't be destroyed : 0x%08x\n",
144 hWnd, GetLastError());
147 static void test_SetWindowTheme(void)
153 SetLastError(0xdeadbeef);
154 hRes = pSetWindowTheme(NULL, NULL, NULL);
157 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
158 ok( GetLastError() == 0xdeadbeef,
159 "Expected 0xdeadbeef, got 0x%08x\n",
163 /* Only do the bare minumum to get a valid hwnd */
164 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
167 SetLastError(0xdeadbeef);
168 hRes = pSetWindowTheme(hWnd, NULL, NULL);
169 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
170 ok( GetLastError() == 0xdeadbeef,
171 "Expected 0xdeadbeef, got 0x%08x\n",
174 bDestroyed = DestroyWindow(hWnd);
176 trace("Window %p couldn't be destroyed : 0x%08x\n",
177 hWnd, GetLastError());
180 static void test_OpenThemeData(void)
182 HTHEME hTheme, hTheme2;
189 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 };
190 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 };
191 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 };
192 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };
194 bThemeActive = pIsThemeActive();
197 SetLastError(0xdeadbeef);
198 hTheme = pOpenThemeData(NULL, NULL);
199 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
201 ok( GetLastError() == E_POINTER,
202 "Expected GLE() to be E_POINTER, got 0x%08x\n",
205 /* A NULL hWnd and an invalid classlist */
206 SetLastError(0xdeadbeef);
207 hTheme = pOpenThemeData(NULL, szInvalidClassList);
208 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
210 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
211 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
214 SetLastError(0xdeadbeef);
215 hTheme = pOpenThemeData(NULL, szClassList);
218 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
220 ok( GetLastError() == ERROR_SUCCESS,
221 "Expected ERROR_SUCCESS, got 0x%08x\n",
226 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
228 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
229 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
233 /* Only do the bare minumum to get a valid hdc */
234 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
237 SetLastError(0xdeadbeef);
238 hTheme = pOpenThemeData(hWnd, NULL);
239 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
241 ok( GetLastError() == E_POINTER,
242 "Expected GLE() to be E_POINTER, got 0x%08x\n",
245 SetLastError(0xdeadbeef);
246 hTheme = pOpenThemeData(hWnd, szInvalidClassList);
247 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
249 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
250 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
255 SetLastError(0xdeadbeef);
256 hTheme = pOpenThemeData(hWnd, szButtonClassList);
257 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
259 ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
260 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
262 trace("No active theme, skipping rest of OpenThemeData tests\n");
266 /* Only do the next checks if we have an active theme */
268 SetLastError(0xdeadbeef);
269 hTheme = pOpenThemeData(hWnd, szButtonClassList);
270 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
272 ok( GetLastError() == ERROR_SUCCESS,
273 "Expected ERROR_SUCCESS, got 0x%08x\n",
276 /* Test with bUtToN instead of Button */
277 SetLastError(0xdeadbeef);
278 hTheme = pOpenThemeData(hWnd, szButtonClassList2);
279 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
281 ok( GetLastError() == ERROR_SUCCESS,
282 "Expected ERROR_SUCCESS, got 0x%08x\n",
285 SetLastError(0xdeadbeef);
286 hTheme = pOpenThemeData(hWnd, szClassList);
287 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
289 ok( GetLastError() == ERROR_SUCCESS,
290 "Expected ERROR_SUCCESS, got 0x%08x\n",
293 /* GetWindowTheme should return the last handle opened by OpenThemeData */
294 SetLastError(0xdeadbeef);
295 hTheme2 = pGetWindowTheme(hWnd);
296 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
298 ok( GetLastError() == 0xdeadbeef,
299 "Expected 0xdeadbeef, got 0x%08x\n",
302 SetLastError(0xdeadbeef);
303 hRes = pCloseThemeData(hTheme);
304 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
305 ok( GetLastError() == 0xdeadbeef,
306 "Expected 0xdeadbeef, got 0x%08x\n",
309 /* Close a second time */
310 SetLastError(0xdeadbeef);
311 hRes = pCloseThemeData(hTheme);
312 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
313 ok( GetLastError() == 0xdeadbeef,
314 "Expected 0xdeadbeef, got 0x%08x\n",
317 /* See if closing makes a difference for GetWindowTheme */
318 SetLastError(0xdeadbeef);
320 hTheme2 = pGetWindowTheme(hWnd);
321 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
323 ok( GetLastError() == 0xdeadbeef,
324 "Expected 0xdeadbeef, got 0x%08x\n",
327 SetLastError(0xdeadbeef);
328 bTPDefined = pIsThemePartDefined(hTheme, 0 , 0);
331 ok( bTPDefined == FALSE, "Expected FALSE\n");
332 ok( GetLastError() == ERROR_SUCCESS,
333 "Expected ERROR_SUCCESS, got 0x%08x\n",
337 bDestroyed = DestroyWindow(hWnd);
339 trace("Window %p couldn't be destroyed : 0x%08x\n",
340 hWnd, GetLastError());
343 static void test_GetCurrentThemeName(void)
347 WCHAR currentTheme[MAX_PATH];
348 WCHAR currentColor[MAX_PATH];
349 WCHAR currentSize[MAX_PATH];
351 bThemeActive = pIsThemeActive();
354 SetLastError(0xdeadbeef);
355 hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
357 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
359 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
360 ok( GetLastError() == 0xdeadbeef,
361 "Expected 0xdeadbeef, got 0x%08x\n",
364 /* Number of characters given is 0 */
365 SetLastError(0xdeadbeef);
366 hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
368 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
370 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
371 ok( GetLastError() == 0xdeadbeef,
372 "Expected 0xdeadbeef, got 0x%08x\n",
375 /* When the number of characters given is too small (not 0, see above), GetCurrentThemeName returns 0x8007007a.
376 * The only definition I found was in strsafe.h:
378 * #define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
380 SetLastError(0xdeadbeef);
381 hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
384 ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes);
386 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
387 ok( GetLastError() == 0xdeadbeef,
388 "Expected 0xdeadbeef, got 0x%08x\n",
391 /* The same is true if the number of characters is too small for Color and/or Size */
392 SetLastError(0xdeadbeef);
393 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR),
395 currentSize, sizeof(currentSize) / sizeof(WCHAR));
398 ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes);
400 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
401 ok( GetLastError() == 0xdeadbeef,
402 "Expected 0xdeadbeef, got 0x%08x\n",
405 /* Given number of characters is correct */
406 SetLastError(0xdeadbeef);
407 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
409 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
411 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
412 ok( GetLastError() == 0xdeadbeef,
413 "Expected 0xdeadbeef, got 0x%08x\n",
416 /* Given number of characters for the theme name is too large */
417 SetLastError(0xdeadbeef);
418 hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0);
420 ok( hRes == E_POINTER, "Expected E_POINTER, 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);