jscript: Added SCRIPTITEM_ISVISIBLE flag implementation.
[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 "vfwmsgs.h"
25 #include "uxtheme.h"
26
27 #include "wine/test.h"
28
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);
37
38 static HMODULE hUxtheme = 0;
39
40 #define UXTHEME_GET_PROC(func) \
41     p ## func = (void*)GetProcAddress(hUxtheme, #func); \
42     if(!p ## func) { \
43       trace("GetProcAddress(%s) failed\n", #func); \
44       FreeLibrary(hUxtheme); \
45       return FALSE; \
46     }
47
48 static BOOL InitFunctionPtrs(void)
49 {
50     hUxtheme = LoadLibraryA("uxtheme.dll");
51     if(!hUxtheme) {
52       trace("Could not load uxtheme.dll\n");
53       return FALSE;
54     }
55     if (hUxtheme)
56     {
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)
65     }
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.
69      */
70     if (!pCloseThemeData || !pGetCurrentThemeName ||
71         !pGetWindowTheme || !pIsAppThemed ||
72         !pIsThemeActive || !pIsThemePartDefined ||
73         !pOpenThemeData || !pSetWindowTheme)
74         return FALSE;
75
76     return TRUE;
77 }
78
79 static void test_IsThemed(void)
80 {
81     BOOL bThemeActive;
82     BOOL bAppThemed;
83     BOOL bTPDefined;
84
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",
90         GetLastError());
91
92     /* This test is not themed */
93     SetLastError(0xdeadbeef);
94     bAppThemed = pIsAppThemed();
95
96     if (bThemeActive)
97         todo_wine
98             ok( bAppThemed == FALSE, "Expected FALSE as this test executable is not (yet) themed.\n");
99     else
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");
102
103     ok( GetLastError() == ERROR_SUCCESS,
104         "Expected ERROR_SUCCESS, got 0x%08x\n",
105         GetLastError());
106
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",
112         GetLastError());
113 }
114
115 static void test_GetWindowTheme(void)
116 {
117     HTHEME    hTheme;
118     HWND      hWnd;
119     BOOL    bDestroyed;
120
121     SetLastError(0xdeadbeef);
122     hTheme = pGetWindowTheme(NULL);
123     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
124     todo_wine
125         ok( GetLastError() == E_HANDLE,
126             "Expected E_HANDLE, got 0x%08x\n",
127             GetLastError());
128
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);
131     if (!hWnd) return;
132
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",
138         GetLastError());
139
140     bDestroyed = DestroyWindow(hWnd);
141     if (!bDestroyed)
142         trace("Window %p couldn't be destroyed : 0x%08x\n",
143             hWnd, GetLastError());
144 }
145
146 static void test_SetWindowTheme(void)
147 {
148     HRESULT hRes;
149     HWND    hWnd;
150     BOOL    bDestroyed;
151
152     SetLastError(0xdeadbeef);
153     hRes = pSetWindowTheme(NULL, NULL, NULL);
154     todo_wine
155     {
156         ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
157         ok( GetLastError() == 0xdeadbeef,
158             "Expected 0xdeadbeef, got 0x%08x\n",
159             GetLastError());
160     }
161
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);
164     if (!hWnd) return;
165
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",
171         GetLastError());
172
173     bDestroyed = DestroyWindow(hWnd);
174     if (!bDestroyed)
175         trace("Window %p couldn't be destroyed : 0x%08x\n",
176             hWnd, GetLastError());
177 }
178
179 static void test_OpenThemeData(void)
180 {
181     HTHEME    hTheme, hTheme2;
182     HWND      hWnd;
183     BOOL      bThemeActive;
184     HRESULT   hRes;
185     BOOL      bDestroyed;
186     BOOL      bTPDefined;
187
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 };
192
193     bThemeActive = pIsThemeActive();
194
195     /* All NULL */
196     SetLastError(0xdeadbeef);
197     hTheme = pOpenThemeData(NULL, NULL);
198     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
199     todo_wine
200         ok( GetLastError() == E_POINTER,
201             "Expected GLE() to be E_POINTER, got 0x%08x\n",
202             GetLastError());
203
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);
208     todo_wine
209         ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
210             "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
211             GetLastError());
212
213     SetLastError(0xdeadbeef);
214     hTheme = pOpenThemeData(NULL, szClassList);
215     if (bThemeActive)
216     {
217         ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
218         todo_wine
219             ok( GetLastError() == ERROR_SUCCESS,
220                 "Expected ERROR_SUCCESS, got 0x%08x\n",
221                 GetLastError());
222     }
223     else
224     {
225         ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
226         todo_wine
227             ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
228                 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
229                 GetLastError());
230     }
231
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);
234     if (!hWnd) return;
235
236     SetLastError(0xdeadbeef);
237     hTheme = pOpenThemeData(hWnd, NULL);
238     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
239     todo_wine
240         ok( GetLastError() == E_POINTER,
241             "Expected GLE() to be E_POINTER, got 0x%08x\n",
242             GetLastError());
243
244     SetLastError(0xdeadbeef);
245     hTheme = pOpenThemeData(hWnd, szInvalidClassList);
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%08x\n",
250             GetLastError());
251
252     if (!bThemeActive)
253     {
254         SetLastError(0xdeadbeef);
255         hTheme = pOpenThemeData(hWnd, szButtonClassList);
256         ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
257         todo_wine
258             ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
259                 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
260                 GetLastError());
261         skip("No active theme, skipping rest of OpenThemeData tests\n");
262         return;
263     }
264
265     /* Only do the next checks if we have an active theme */
266
267     SetLastError(0xdeadbeef);
268     hTheme = pOpenThemeData(hWnd, szButtonClassList);
269     ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
270     todo_wine
271         ok( GetLastError() == ERROR_SUCCESS,
272             "Expected ERROR_SUCCESS, got 0x%08x\n",
273             GetLastError());
274
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");
279     todo_wine
280         ok( GetLastError() == ERROR_SUCCESS,
281             "Expected ERROR_SUCCESS, got 0x%08x\n",
282             GetLastError());
283
284     SetLastError(0xdeadbeef);
285     hTheme = pOpenThemeData(hWnd, szClassList);
286     ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
287     todo_wine
288         ok( GetLastError() == ERROR_SUCCESS,
289             "Expected ERROR_SUCCESS, got 0x%08x\n",
290             GetLastError());
291
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",
296         hTheme, hTheme2);
297     ok( GetLastError() == 0xdeadbeef,
298         "Expected 0xdeadbeef, got 0x%08x\n",
299         GetLastError());
300
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",
306         GetLastError());
307
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",
314         GetLastError());
315
316     /* See if closing makes a difference for GetWindowTheme */
317     SetLastError(0xdeadbeef);
318     hTheme2 = NULL;
319     hTheme2 = pGetWindowTheme(hWnd);
320     ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
321         hTheme, hTheme2);
322     ok( GetLastError() == 0xdeadbeef,
323         "Expected 0xdeadbeef, got 0x%08x\n",
324         GetLastError());
325
326     SetLastError(0xdeadbeef);
327     bTPDefined = pIsThemePartDefined(hTheme, 0 , 0);
328     todo_wine
329     {
330         ok( bTPDefined == FALSE, "Expected FALSE\n");
331         ok( GetLastError() == ERROR_SUCCESS,
332             "Expected ERROR_SUCCESS, got 0x%08x\n",
333             GetLastError());
334     }
335
336     bDestroyed = DestroyWindow(hWnd);
337     if (!bDestroyed)
338         trace("Window %p couldn't be destroyed : 0x%08x\n",
339             hWnd, GetLastError());
340 }
341
342 static void test_GetCurrentThemeName(void)
343 {
344     BOOL    bThemeActive;
345     HRESULT hRes;
346     WCHAR currentTheme[MAX_PATH];
347     WCHAR currentColor[MAX_PATH];
348     WCHAR currentSize[MAX_PATH];
349
350     bThemeActive = pIsThemeActive();
351
352     /* All NULLs */
353     SetLastError(0xdeadbeef);
354     hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
355     if (bThemeActive)
356         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
357     else
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",
361         GetLastError());
362
363     /* Number of characters given is 0 */
364     SetLastError(0xdeadbeef);
365     hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
366     if (bThemeActive)
367         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
368     else
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",
372         GetLastError());
373
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:
376      *
377      * #define STRSAFE_E_INSUFFICIENT_BUFFER       ((HRESULT)0x8007007AL)  // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
378      */
379     SetLastError(0xdeadbeef);
380     hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
381     if (bThemeActive)
382         todo_wine
383             ok(hRes == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes);
384     else
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",
388         GetLastError());
389
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), 
393                                 currentColor, 2,
394                                 currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
395     if (bThemeActive)
396         todo_wine
397             ok(hRes == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes);
398     else
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",
402         GetLastError());
403
404     /* Given number of characters is correct */
405     SetLastError(0xdeadbeef);
406     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
407     if (bThemeActive)
408         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
409     else
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",
413         GetLastError());
414
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);
418     if (bThemeActive)
419         ok( hRes == E_POINTER || hRes == S_OK, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes);
420     else
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",
426         GetLastError());
427  
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));
433     if (bThemeActive)
434         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
435     else
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",
439         GetLastError());
440
441     SetLastError(0xdeadbeef);
442     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
443                                 currentColor, sizeof(currentTheme) / sizeof(WCHAR),
444                                 currentSize,  sizeof(currentSize));
445     if (bThemeActive)
446         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
447     else
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",
451         GetLastError());
452
453     /* Correct call */
454     SetLastError(0xdeadbeef);
455     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
456                                 currentColor, sizeof(currentColor) / sizeof(WCHAR),
457                                 currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
458     if (bThemeActive)
459         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
460     else
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",
464         GetLastError());
465 }
466
467 static void test_CloseThemeData(void)
468 {
469     HRESULT hRes;
470
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",
476         GetLastError());
477 }
478
479 START_TEST(system)
480 {
481     if(!InitFunctionPtrs())
482         return;
483
484     /* No real functional tests will be done (yet). The current tests
485      * only show input/return behaviour
486      */
487
488     /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
489     trace("Starting test_IsThemed()\n");
490     test_IsThemed();
491
492     /* GetWindowTheme */
493     trace("Starting test_GetWindowTheme()\n");
494     test_GetWindowTheme();
495
496     /* SetWindowTheme */
497     trace("Starting test_SetWindowTheme()\n");
498     test_SetWindowTheme();
499
500     /* OpenThemeData, a bit more functional now */
501     trace("Starting test_OpenThemeData()\n");
502     test_OpenThemeData();
503
504     /* GetCurrentThemeName */
505     trace("Starting test_GetCurrentThemeName()\n");
506     test_GetCurrentThemeName();
507
508     /* CloseThemeData */
509     trace("Starting test_CloseThemeData()\n");
510     test_CloseThemeData();
511
512     FreeLibrary(hUxtheme);
513 }