wined3d: Implement more GLSL instructions and a little cleanup.
[wine] / dlls / uxtheme / tests / system.c
1 /* Unit test suite for uxtheme API functions
2  *
3  * Copyright 2006 Paul Vriens
4  *
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.
9  *
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.
14  *
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
18  *
19  */
20
21 #include <stdarg.h>
22
23 #include "windows.h"
24 #include "uxtheme.h"
25
26 #include "wine/test.h"
27
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);
35
36 static HMODULE hUxtheme = 0;
37
38 #define UXTHEME_GET_PROC(func) \
39     p ## func = (void*)GetProcAddress(hUxtheme, #func); \
40     if(!p ## func) { \
41       trace("GetProcAddress(%s) failed\n", #func); \
42       FreeLibrary(hUxtheme); \
43       return FALSE; \
44     }
45
46 static BOOL InitFunctionPtrs(void)
47 {
48     hUxtheme = LoadLibraryA("uxtheme.dll");
49     if(!hUxtheme) {
50       trace("Could not load uxtheme.dll\n");
51       return FALSE;
52     }
53     if (hUxtheme)
54     {
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)
62     }
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.
66      */
67     if (!pCloseThemeData || !pGetWindowTheme ||
68         !pIsAppThemed || !pIsThemeActive ||
69         !pOpenThemeData || !pSetWindowTheme ||
70         !pGetCurrentThemeName)
71         return FALSE;
72
73     return TRUE;
74 }
75
76 static void test_IsThemed(void)
77 {
78     BOOL bThemeActive;
79     BOOL bAppThemed;
80
81     SetLastError(0xdeadbeef);
82     bThemeActive = pIsThemeActive();
83     trace("Theming is %s\n", (bThemeActive) ? "active" : "inactive");
84     todo_wine
85         ok( GetLastError() == ERROR_SUCCESS,
86             "Expected ERROR_SUCCESS, got 0x%08lx\n",
87             GetLastError());
88
89     /* This test is not themed */
90     SetLastError(0xdeadbeef);
91     bAppThemed = pIsAppThemed();
92
93     if (bThemeActive)
94         todo_wine
95             ok( bAppThemed == FALSE, "Expected FALSE as this test executable is not (yet) themed.\n");
96     else
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");
99
100     todo_wine
101         ok( GetLastError() == ERROR_SUCCESS,
102             "Expected ERROR_SUCCESS, got 0x%08lx\n",
103             GetLastError());
104 }
105
106 static void test_GetWindowTheme(void)
107 {
108     HTHEME    hTheme;
109     HWND      hWnd;
110     BOOL    bDestroyed;
111
112     SetLastError(0xdeadbeef);
113     hTheme = pGetWindowTheme(NULL);
114     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
115     todo_wine
116         ok( GetLastError() == E_HANDLE,
117             "Expected E_HANDLE, got 0x%08lx\n",
118             GetLastError());
119
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);
122     if (!hWnd) return;
123
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",
129         GetLastError());
130
131     bDestroyed = DestroyWindow(hWnd);
132     if (!bDestroyed)
133         trace("Window %p couldn't be destroyed : 0x%08lx\n",
134             hWnd, GetLastError());
135 }
136
137 static void test_SetWindowTheme(void)
138 {
139     HRESULT hRes;
140     HWND    hWnd;
141     BOOL    bDestroyed;
142
143     SetLastError(0xdeadbeef);
144     hRes = pSetWindowTheme(NULL, NULL, NULL);
145     todo_wine
146     {
147         ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08lx\n", hRes);
148         ok( GetLastError() == 0xdeadbeef,
149             "Expected 0xdeadbeef, got 0x%08lx\n",
150             GetLastError());
151     }
152
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);
155     if (!hWnd) return;
156
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",
162         GetLastError());
163
164     bDestroyed = DestroyWindow(hWnd);
165     if (!bDestroyed)
166         trace("Window %p couldn't be destroyed : 0x%08lx\n",
167             hWnd, GetLastError());
168 }
169
170 static void test_OpenThemeData(void)
171 {
172     HTHEME    hTheme, hTheme2;
173     HWND      hWnd;
174     BOOL      bThemeActive;
175     HRESULT   hRes;
176     BOOL      bDestroyed;
177
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 };
182
183     bThemeActive = pIsThemeActive();
184
185     /* All NULL */
186     SetLastError(0xdeadbeef);
187     hTheme = pOpenThemeData(NULL, NULL);
188     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
189     todo_wine
190         ok( GetLastError() == E_POINTER,
191             "Expected GLE() to be E_POINTER, got 0x%08lx\n",
192             GetLastError());
193
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);
198     todo_wine
199         ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
200             "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
201             GetLastError());
202
203     SetLastError(0xdeadbeef);
204     hTheme = pOpenThemeData(NULL, szClassList);
205     if (bThemeActive)
206     {
207         ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
208         todo_wine
209             ok( GetLastError() == ERROR_SUCCESS,
210                 "Expected ERROR_SUCCESS, got 0x%08lx\n",
211                 GetLastError());
212     }
213     else
214     {
215         ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
216         todo_wine
217             ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
218                 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
219                 GetLastError());
220     }
221
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);
224     if (!hWnd) return;
225
226     SetLastError(0xdeadbeef);
227     hTheme = pOpenThemeData(hWnd, NULL);
228     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
229     todo_wine
230         ok( GetLastError() == E_POINTER,
231             "Expected GLE() to be E_POINTER, got 0x%08lx\n",
232             GetLastError());
233
234     SetLastError(0xdeadbeef);
235     hTheme = pOpenThemeData(hWnd, szInvalidClassList);
236     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
237     todo_wine
238         ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
239             "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
240             GetLastError());
241
242     if (!bThemeActive)
243     {
244         SetLastError(0xdeadbeef);
245         hTheme = pOpenThemeData(hWnd, szButtonClassList);
246         ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
247         todo_wine
248             ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
249                 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08lx\n",
250                 GetLastError());
251         trace("No active theme, skipping rest of OpenThemeData tests\n");
252         return;
253     }
254
255     /* Only do the next checks if we have an active theme */
256
257     SetLastError(0xdeadbeef);
258     hTheme = pOpenThemeData(hWnd, szButtonClassList);
259     ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
260     todo_wine
261         ok( GetLastError() == ERROR_SUCCESS,
262             "Expected ERROR_SUCCESS, got 0x%08lx\n",
263             GetLastError());
264
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");
269     todo_wine
270         ok( GetLastError() == ERROR_SUCCESS,
271             "Expected ERROR_SUCCESS, got 0x%08lx\n",
272             GetLastError());
273
274     SetLastError(0xdeadbeef);
275     hTheme = pOpenThemeData(hWnd, szClassList);
276     ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
277     todo_wine
278         ok( GetLastError() == ERROR_SUCCESS,
279             "Expected ERROR_SUCCESS, got 0x%08lx\n",
280             GetLastError());
281
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",
286         hTheme, hTheme2);
287     ok( GetLastError() == 0xdeadbeef,
288         "Expected 0xdeadbeef, got 0x%08lx\n",
289         GetLastError());
290
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",
296         GetLastError());
297
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",
304         GetLastError());
305
306     /* See if closing makes a difference for GetWindowTheme */
307     SetLastError(0xdeadbeef);
308     hTheme2 = NULL;
309     hTheme2 = pGetWindowTheme(hWnd);
310     ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
311         hTheme, hTheme2);
312     ok( GetLastError() == 0xdeadbeef,
313         "Expected 0xdeadbeef, got 0x%08lx\n",
314         GetLastError());
315
316     bDestroyed = DestroyWindow(hWnd);
317     if (!bDestroyed)
318         trace("Window %p couldn't be destroyed : 0x%08lx\n",
319             hWnd, GetLastError());
320 }
321
322 static void test_GetCurrentThemeName(void)
323 {
324     BOOL    bThemeActive;
325     HRESULT hRes;
326     WCHAR currentTheme[MAX_PATH];
327     WCHAR currentColor[MAX_PATH];
328     WCHAR currentSize[MAX_PATH];
329
330     bThemeActive = pIsThemeActive();
331
332     /* All NULLs */
333     SetLastError(0xdeadbeef);
334     hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
335     if (bThemeActive)
336         ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
337     else
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",
341         GetLastError());
342
343     /* Number of characters given is 0 */
344     SetLastError(0xdeadbeef);
345     hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
346     if (bThemeActive)
347         ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
348     else
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",
352         GetLastError());
353
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:
356      *
357      * #define STRSAFE_E_INSUFFICIENT_BUFFER       ((HRESULT)0x8007007AL)  // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
358      */
359     SetLastError(0xdeadbeef);
360     hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
361     if (bThemeActive)
362         todo_wine
363             ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08lx\n", hRes);
364     else
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",
368         GetLastError());
369
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), 
373                                 currentColor, 2,
374                                 currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
375     if (bThemeActive)
376         todo_wine
377             ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08lx\n", hRes);
378     else
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",
382         GetLastError());
383
384     /* Given number of characters is correct */
385     SetLastError(0xdeadbeef);
386     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
387     if (bThemeActive)
388         ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
389     else
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",
393         GetLastError());
394
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);
398     todo_wine
399         ok( hRes == E_POINTER, "Expected E_POINTER, got 0x%08lx\n", hRes);
400     ok( GetLastError() == 0xdeadbeef,
401         "Expected 0xdeadbeef, got 0x%08lx\n",
402         GetLastError());
403  
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));
409     if (bThemeActive)
410         ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
411     else
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",
415         GetLastError());
416
417     SetLastError(0xdeadbeef);
418     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
419                                 currentColor, sizeof(currentTheme) / sizeof(WCHAR),
420                                 currentSize,  sizeof(currentSize));
421     if (bThemeActive)
422         ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
423     else
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",
427         GetLastError());
428
429     /* Correct call */
430     SetLastError(0xdeadbeef);
431     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
432                                 currentColor, sizeof(currentColor) / sizeof(WCHAR),
433                                 currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
434     if (bThemeActive)
435         ok( hRes == S_OK, "Expected S_OK, got 0x%08lx\n", hRes);
436     else
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",
440         GetLastError());
441 }
442
443 static void test_CloseThemeData(void)
444 {
445     HRESULT hRes;
446
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",
452         GetLastError());
453 }
454
455 START_TEST(system)
456 {
457     if(!InitFunctionPtrs())
458         return;
459
460     /* No real functional tests will be done (yet). The current tests
461      * only show input/return behaviour
462      */
463
464     /* IsThemeActive and IsAppThemed */
465     trace("Starting test_IsThemed()\n");
466     test_IsThemed();
467
468     /* GetWindowTheme */
469     trace("Starting test_GetWindowTheme()\n");
470     test_GetWindowTheme();
471
472     /* SetWindowTheme */
473     trace("Starting test_SetWindowTheme()\n");
474     test_SetWindowTheme();
475
476     /* OpenThemeData, a bit more functional now */
477     trace("Starting test_OpenThemeData()\n");
478     test_OpenThemeData();
479
480     /* GetCurrentThemeName */
481     trace("Starting test_GetCurrentThemeName()\n");
482     test_GetCurrentThemeName();
483
484     /* CloseThemeData */
485     trace("Starting test_CloseThemeData()\n");
486     test_CloseThemeData();
487
488     FreeLibrary(hUxtheme);
489 }