dinput: Move SetEventNotification and associated event into base class.
[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 BOOL    (WINAPI * pIsThemePartDefined)(HTHEME, int, int);
34 static HTHEME  (WINAPI * pOpenThemeData)(HWND, LPCWSTR);
35 static HRESULT (WINAPI * pSetWindowTheme)(HWND, LPCWSTR, LPCWSTR);
36
37 static HMODULE hUxtheme = 0;
38
39 #define UXTHEME_GET_PROC(func) \
40     p ## func = (void*)GetProcAddress(hUxtheme, #func); \
41     if(!p ## func) { \
42       trace("GetProcAddress(%s) failed\n", #func); \
43       FreeLibrary(hUxtheme); \
44       return FALSE; \
45     }
46
47 static BOOL InitFunctionPtrs(void)
48 {
49     hUxtheme = LoadLibraryA("uxtheme.dll");
50     if(!hUxtheme) {
51       trace("Could not load uxtheme.dll\n");
52       return FALSE;
53     }
54     if (hUxtheme)
55     {
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)
64     }
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.
68      */
69     if (!pCloseThemeData || !pGetCurrentThemeName ||
70         !pGetWindowTheme || !pIsAppThemed ||
71         !pIsThemeActive || !pIsThemePartDefined ||
72         !pOpenThemeData || !pSetWindowTheme)
73         return FALSE;
74
75     return TRUE;
76 }
77
78 static void test_IsThemed(void)
79 {
80     BOOL bThemeActive;
81     BOOL bAppThemed;
82     BOOL bTPDefined;
83
84     SetLastError(0xdeadbeef);
85     bThemeActive = pIsThemeActive();
86     trace("Theming is %s\n", (bThemeActive) ? "active" : "inactive");
87     todo_wine
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     todo_wine
104         ok( GetLastError() == ERROR_SUCCESS,
105             "Expected ERROR_SUCCESS, got 0x%08x\n",
106             GetLastError());
107
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",
113         GetLastError());
114 }
115
116 static void test_GetWindowTheme(void)
117 {
118     HTHEME    hTheme;
119     HWND      hWnd;
120     BOOL    bDestroyed;
121
122     SetLastError(0xdeadbeef);
123     hTheme = pGetWindowTheme(NULL);
124     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
125     todo_wine
126         ok( GetLastError() == E_HANDLE,
127             "Expected E_HANDLE, got 0x%08x\n",
128             GetLastError());
129
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);
132     if (!hWnd) return;
133
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",
139         GetLastError());
140
141     bDestroyed = DestroyWindow(hWnd);
142     if (!bDestroyed)
143         trace("Window %p couldn't be destroyed : 0x%08x\n",
144             hWnd, GetLastError());
145 }
146
147 static void test_SetWindowTheme(void)
148 {
149     HRESULT hRes;
150     HWND    hWnd;
151     BOOL    bDestroyed;
152
153     SetLastError(0xdeadbeef);
154     hRes = pSetWindowTheme(NULL, NULL, NULL);
155     todo_wine
156     {
157         ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
158         ok( GetLastError() == 0xdeadbeef,
159             "Expected 0xdeadbeef, got 0x%08x\n",
160             GetLastError());
161     }
162
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);
165     if (!hWnd) return;
166
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",
172         GetLastError());
173
174     bDestroyed = DestroyWindow(hWnd);
175     if (!bDestroyed)
176         trace("Window %p couldn't be destroyed : 0x%08x\n",
177             hWnd, GetLastError());
178 }
179
180 static void test_OpenThemeData(void)
181 {
182     HTHEME    hTheme, hTheme2;
183     HWND      hWnd;
184     BOOL      bThemeActive;
185     HRESULT   hRes;
186     BOOL      bDestroyed;
187     BOOL      bTPDefined;
188
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 };
193
194     bThemeActive = pIsThemeActive();
195
196     /* All NULL */
197     SetLastError(0xdeadbeef);
198     hTheme = pOpenThemeData(NULL, NULL);
199     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
200     todo_wine
201         ok( GetLastError() == E_POINTER,
202             "Expected GLE() to be E_POINTER, got 0x%08x\n",
203             GetLastError());
204
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);
209     todo_wine
210         ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
211             "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
212             GetLastError());
213
214     SetLastError(0xdeadbeef);
215     hTheme = pOpenThemeData(NULL, szClassList);
216     if (bThemeActive)
217     {
218         ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
219         todo_wine
220             ok( GetLastError() == ERROR_SUCCESS,
221                 "Expected ERROR_SUCCESS, got 0x%08x\n",
222                 GetLastError());
223     }
224     else
225     {
226         ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
227         todo_wine
228             ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
229                 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
230                 GetLastError());
231     }
232
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);
235     if (!hWnd) return;
236
237     SetLastError(0xdeadbeef);
238     hTheme = pOpenThemeData(hWnd, NULL);
239     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
240     todo_wine
241         ok( GetLastError() == E_POINTER,
242             "Expected GLE() to be E_POINTER, got 0x%08x\n",
243             GetLastError());
244
245     SetLastError(0xdeadbeef);
246     hTheme = pOpenThemeData(hWnd, szInvalidClassList);
247     ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
248     todo_wine
249         ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
250             "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
251             GetLastError());
252
253     if (!bThemeActive)
254     {
255         SetLastError(0xdeadbeef);
256         hTheme = pOpenThemeData(hWnd, szButtonClassList);
257         ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
258         todo_wine
259             ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
260                 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
261                 GetLastError());
262         trace("No active theme, skipping rest of OpenThemeData tests\n");
263         return;
264     }
265
266     /* Only do the next checks if we have an active theme */
267
268     SetLastError(0xdeadbeef);
269     hTheme = pOpenThemeData(hWnd, szButtonClassList);
270     ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
271     todo_wine
272         ok( GetLastError() == ERROR_SUCCESS,
273             "Expected ERROR_SUCCESS, got 0x%08x\n",
274             GetLastError());
275
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");
280     todo_wine
281         ok( GetLastError() == ERROR_SUCCESS,
282             "Expected ERROR_SUCCESS, got 0x%08x\n",
283             GetLastError());
284
285     SetLastError(0xdeadbeef);
286     hTheme = pOpenThemeData(hWnd, szClassList);
287     ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
288     todo_wine
289         ok( GetLastError() == ERROR_SUCCESS,
290             "Expected ERROR_SUCCESS, got 0x%08x\n",
291             GetLastError());
292
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",
297         hTheme, hTheme2);
298     ok( GetLastError() == 0xdeadbeef,
299         "Expected 0xdeadbeef, got 0x%08x\n",
300         GetLastError());
301
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",
307         GetLastError());
308
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",
315         GetLastError());
316
317     /* See if closing makes a difference for GetWindowTheme */
318     SetLastError(0xdeadbeef);
319     hTheme2 = NULL;
320     hTheme2 = pGetWindowTheme(hWnd);
321     ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
322         hTheme, hTheme2);
323     ok( GetLastError() == 0xdeadbeef,
324         "Expected 0xdeadbeef, got 0x%08x\n",
325         GetLastError());
326
327     SetLastError(0xdeadbeef);
328     bTPDefined = pIsThemePartDefined(hTheme, 0 , 0);
329     todo_wine
330     {
331         ok( bTPDefined == FALSE, "Expected FALSE\n");
332         ok( GetLastError() == ERROR_SUCCESS,
333             "Expected ERROR_SUCCESS, got 0x%08x\n",
334             GetLastError());
335     }
336
337     bDestroyed = DestroyWindow(hWnd);
338     if (!bDestroyed)
339         trace("Window %p couldn't be destroyed : 0x%08x\n",
340             hWnd, GetLastError());
341 }
342
343 static void test_GetCurrentThemeName(void)
344 {
345     BOOL    bThemeActive;
346     HRESULT hRes;
347     WCHAR currentTheme[MAX_PATH];
348     WCHAR currentColor[MAX_PATH];
349     WCHAR currentSize[MAX_PATH];
350
351     bThemeActive = pIsThemeActive();
352
353     /* All NULLs */
354     SetLastError(0xdeadbeef);
355     hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
356     if (bThemeActive)
357         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
358     else
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",
362         GetLastError());
363
364     /* Number of characters given is 0 */
365     SetLastError(0xdeadbeef);
366     hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
367     if (bThemeActive)
368         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
369     else
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",
373         GetLastError());
374
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:
377      *
378      * #define STRSAFE_E_INSUFFICIENT_BUFFER       ((HRESULT)0x8007007AL)  // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
379      */
380     SetLastError(0xdeadbeef);
381     hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
382     if (bThemeActive)
383         todo_wine
384             ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes);
385     else
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",
389         GetLastError());
390
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), 
394                                 currentColor, 2,
395                                 currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
396     if (bThemeActive)
397         todo_wine
398             ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes);
399     else
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",
403         GetLastError());
404
405     /* Given number of characters is correct */
406     SetLastError(0xdeadbeef);
407     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
408     if (bThemeActive)
409         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
410     else
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",
414         GetLastError());
415
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);
419     todo_wine
420         ok( hRes == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hRes);
421     ok( GetLastError() == 0xdeadbeef,
422         "Expected 0xdeadbeef, got 0x%08x\n",
423         GetLastError());
424  
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));
430     if (bThemeActive)
431         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
432     else
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",
436         GetLastError());
437
438     SetLastError(0xdeadbeef);
439     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
440                                 currentColor, sizeof(currentTheme) / sizeof(WCHAR),
441                                 currentSize,  sizeof(currentSize));
442     if (bThemeActive)
443         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
444     else
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",
448         GetLastError());
449
450     /* Correct call */
451     SetLastError(0xdeadbeef);
452     hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
453                                 currentColor, sizeof(currentColor) / sizeof(WCHAR),
454                                 currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
455     if (bThemeActive)
456         ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
457     else
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",
461         GetLastError());
462 }
463
464 static void test_CloseThemeData(void)
465 {
466     HRESULT hRes;
467
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",
473         GetLastError());
474 }
475
476 START_TEST(system)
477 {
478     if(!InitFunctionPtrs())
479         return;
480
481     /* No real functional tests will be done (yet). The current tests
482      * only show input/return behaviour
483      */
484
485     /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
486     trace("Starting test_IsThemed()\n");
487     test_IsThemed();
488
489     /* GetWindowTheme */
490     trace("Starting test_GetWindowTheme()\n");
491     test_GetWindowTheme();
492
493     /* SetWindowTheme */
494     trace("Starting test_SetWindowTheme()\n");
495     test_SetWindowTheme();
496
497     /* OpenThemeData, a bit more functional now */
498     trace("Starting test_OpenThemeData()\n");
499     test_OpenThemeData();
500
501     /* GetCurrentThemeName */
502     trace("Starting test_GetCurrentThemeName()\n");
503     test_GetCurrentThemeName();
504
505     /* CloseThemeData */
506     trace("Starting test_CloseThemeData()\n");
507     test_CloseThemeData();
508
509     FreeLibrary(hUxtheme);
510 }