system.c 17.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/* Unit test suite for uxtheme API functions
 *
 * Copyright 2006 Paul Vriens
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */

#include <stdarg.h>

#include "windows.h"
24
#include "vfwmsgs.h"
25 26 27 28 29
#include "uxtheme.h"

#include "wine/test.h"

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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
static HTHEME  (WINAPI * pOpenThemeData)(HWND, LPCWSTR);
static HRESULT (WINAPI * pSetWindowTheme)(HWND, LPCWSTR, LPCWSTR);

static HMODULE hUxtheme = 0;

#define UXTHEME_GET_PROC(func) \
    p ## func = (void*)GetProcAddress(hUxtheme, #func); \
    if(!p ## func) { \
      trace("GetProcAddress(%s) failed\n", #func); \
      FreeLibrary(hUxtheme); \
      return FALSE; \
    }

static BOOL InitFunctionPtrs(void)
{
    hUxtheme = LoadLibraryA("uxtheme.dll");
    if(!hUxtheme) {
      trace("Could not load uxtheme.dll\n");
      return FALSE;
    }
    if (hUxtheme)
    {
      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 64 65
      UXTHEME_GET_PROC(OpenThemeData)
      UXTHEME_GET_PROC(SetWindowTheme)
    }
66 67 68 69
    /* The following functions should be available, if not return FALSE. The Vista functions will
     * be checked (at some point in time) within the single tests if needed. All used functions for
     * now are present on WinXP, W2K3 and Wine.
     */
70 71 72 73
    if (!pCloseThemeData || !pGetCurrentThemeName ||
        !pGetWindowTheme || !pIsAppThemed ||
        !pIsThemeActive || !pIsThemePartDefined ||
        !pOpenThemeData || !pSetWindowTheme)
74 75
        return FALSE;

76 77 78
    return TRUE;
}

79 80 81 82
static void test_IsThemed(void)
{
    BOOL bThemeActive;
    BOOL bAppThemed;
83
    BOOL bTPDefined;
84 85 86 87 88 89

    SetLastError(0xdeadbeef);
    bThemeActive = pIsThemeActive();
    trace("Theming is %s\n", (bThemeActive) ? "active" : "inactive");
    todo_wine
        ok( GetLastError() == ERROR_SUCCESS,
90
            "Expected ERROR_SUCCESS, got 0x%08x\n",
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
            GetLastError());

    /* This test is not themed */
    SetLastError(0xdeadbeef);
    bAppThemed = pIsAppThemed();

    if (bThemeActive)
        todo_wine
            ok( bAppThemed == FALSE, "Expected FALSE as this test executable is not (yet) themed.\n");
    else
        /* Although Wine currently returns FALSE, the logic behind it is wrong. It is not a todo_wine though in the testing sense */
        ok( bAppThemed == FALSE, "Expected FALSE as this test executable is not (yet) themed.\n");

    todo_wine
        ok( GetLastError() == ERROR_SUCCESS,
106
            "Expected ERROR_SUCCESS, got 0x%08x\n",
107
            GetLastError());
108 109 110 111 112

    SetLastError(0xdeadbeef);
    bTPDefined = pIsThemePartDefined(NULL, 0 , 0);
    ok( bTPDefined == FALSE, "Expected FALSE\n");
    ok( GetLastError() == E_HANDLE,
113
        "Expected E_HANDLE, got 0x%08x\n",
114
        GetLastError());
115 116
}

117 118 119 120
static void test_GetWindowTheme(void)
{
    HTHEME    hTheme;
    HWND      hWnd;
121
    BOOL    bDestroyed;
122 123 124 125 126 127

    SetLastError(0xdeadbeef);
    hTheme = pGetWindowTheme(NULL);
    ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
    todo_wine
        ok( GetLastError() == E_HANDLE,
128
            "Expected E_HANDLE, got 0x%08x\n",
129 130 131 132 133 134 135 136 137 138
            GetLastError());

    /* Only do the bare minumum to get a valid hwnd */
    hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
    if (!hWnd) return;

    SetLastError(0xdeadbeef);
    hTheme = pGetWindowTheme(hWnd);
    ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
    ok( GetLastError() == 0xdeadbeef,
139
        "Expected 0xdeadbeef, got 0x%08x\n",
140
        GetLastError());
141 142 143

    bDestroyed = DestroyWindow(hWnd);
    if (!bDestroyed)
144
        trace("Window %p couldn't be destroyed : 0x%08x\n",
145
            hWnd, GetLastError());
146 147
}

148 149 150 151
static void test_SetWindowTheme(void)
{
    HRESULT hRes;
    HWND    hWnd;
152
    BOOL    bDestroyed;
153 154 155 156

    SetLastError(0xdeadbeef);
    hRes = pSetWindowTheme(NULL, NULL, NULL);
    todo_wine
157
    {
158
        ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
159
        ok( GetLastError() == 0xdeadbeef,
160
            "Expected 0xdeadbeef, got 0x%08x\n",
161 162
            GetLastError());
    }
163 164 165 166 167 168 169

    /* Only do the bare minumum to get a valid hwnd */
    hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
    if (!hWnd) return;

    SetLastError(0xdeadbeef);
    hRes = pSetWindowTheme(hWnd, NULL, NULL);
170
    ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
171
    ok( GetLastError() == 0xdeadbeef,
172
        "Expected 0xdeadbeef, got 0x%08x\n",
173
        GetLastError());
174 175 176

    bDestroyed = DestroyWindow(hWnd);
    if (!bDestroyed)
177
        trace("Window %p couldn't be destroyed : 0x%08x\n",
178
            hWnd, GetLastError());
179 180 181 182
}

static void test_OpenThemeData(void)
{
183
    HTHEME    hTheme, hTheme2;
184 185
    HWND      hWnd;
    BOOL      bThemeActive;
186
    HRESULT   hRes;
187
    BOOL      bDestroyed;
188
    BOOL      bTPDefined;
189 190 191

    WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 };
    WCHAR szButtonClassList[]  = {'B','u','t','t','o','n', 0 };
192
    WCHAR szButtonClassList2[]  = {'b','U','t','T','o','N', 0 };
193 194 195 196 197 198 199 200 201 202
    WCHAR szClassList[]        = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 };

    bThemeActive = pIsThemeActive();

    /* All NULL */
    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(NULL, NULL);
    ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
    todo_wine
        ok( GetLastError() == E_POINTER,
203
            "Expected GLE() to be E_POINTER, got 0x%08x\n",
204 205 206 207 208 209 210 211
            GetLastError());

    /* A NULL hWnd and an invalid classlist */
    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(NULL, szInvalidClassList);
    ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
    todo_wine
        ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
212
            "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
213 214 215 216 217 218 219 220
            GetLastError());

    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(NULL, szClassList);
    if (bThemeActive)
    {
        ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
        todo_wine
221
            ok( GetLastError() == ERROR_SUCCESS,
222
                "Expected ERROR_SUCCESS, got 0x%08x\n",
223 224 225 226 227 228 229
                GetLastError());
    }
    else
    {
        ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
        todo_wine
            ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
230
                "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
231 232 233 234 235 236 237 238 239 240 241 242
                GetLastError());
    }

    /* Only do the bare minumum to get a valid hdc */
    hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
    if (!hWnd) return;

    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(hWnd, NULL);
    ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
    todo_wine
        ok( GetLastError() == E_POINTER,
243
            "Expected GLE() to be E_POINTER, got 0x%08x\n",
244 245 246 247 248 249 250
            GetLastError());

    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(hWnd, szInvalidClassList);
    ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
    todo_wine
        ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
251
            "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
252 253 254 255 256 257 258 259 260
            GetLastError());

    if (!bThemeActive)
    {
        SetLastError(0xdeadbeef);
        hTheme = pOpenThemeData(hWnd, szButtonClassList);
        ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme);
        todo_wine
            ok( GetLastError() == E_PROP_ID_UNSUPPORTED,
261
                "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n",
262 263 264 265 266 267 268 269 270 271 272
                GetLastError());
        trace("No active theme, skipping rest of OpenThemeData tests\n");
        return;
    }

    /* Only do the next checks if we have an active theme */

    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(hWnd, szButtonClassList);
    ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
    todo_wine
273
        ok( GetLastError() == ERROR_SUCCESS,
274
            "Expected ERROR_SUCCESS, got 0x%08x\n",
275 276
            GetLastError());

277 278 279 280 281 282
    /* Test with bUtToN instead of Button */
    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(hWnd, szButtonClassList2);
    ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
    todo_wine
        ok( GetLastError() == ERROR_SUCCESS,
283
            "Expected ERROR_SUCCESS, got 0x%08x\n",
284 285
            GetLastError());

286 287 288 289
    SetLastError(0xdeadbeef);
    hTheme = pOpenThemeData(hWnd, szClassList);
    ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n");
    todo_wine
290
        ok( GetLastError() == ERROR_SUCCESS,
291
            "Expected ERROR_SUCCESS, got 0x%08x\n",
292
            GetLastError());
293

294 295 296 297 298 299
    /* GetWindowTheme should return the last handle opened by OpenThemeData */
    SetLastError(0xdeadbeef);
    hTheme2 = pGetWindowTheme(hWnd);
    ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
        hTheme, hTheme2);
    ok( GetLastError() == 0xdeadbeef,
300
        "Expected 0xdeadbeef, got 0x%08x\n",
301 302 303 304
        GetLastError());

    SetLastError(0xdeadbeef);
    hRes = pCloseThemeData(hTheme);
305
    ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
306
    ok( GetLastError() == 0xdeadbeef,
307
        "Expected 0xdeadbeef, got 0x%08x\n",
308 309 310 311 312
        GetLastError());

    /* Close a second time */
    SetLastError(0xdeadbeef);
    hRes = pCloseThemeData(hTheme);
313
    ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
314
    ok( GetLastError() == 0xdeadbeef,
315
        "Expected 0xdeadbeef, got 0x%08x\n",
316 317 318 319 320 321 322 323 324
        GetLastError());

    /* See if closing makes a difference for GetWindowTheme */
    SetLastError(0xdeadbeef);
    hTheme2 = NULL;
    hTheme2 = pGetWindowTheme(hWnd);
    ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n",
        hTheme, hTheme2);
    ok( GetLastError() == 0xdeadbeef,
325
        "Expected 0xdeadbeef, got 0x%08x\n",
326 327
        GetLastError());

328 329 330 331 332 333
    SetLastError(0xdeadbeef);
    bTPDefined = pIsThemePartDefined(hTheme, 0 , 0);
    todo_wine
    {
        ok( bTPDefined == FALSE, "Expected FALSE\n");
        ok( GetLastError() == ERROR_SUCCESS,
334
            "Expected ERROR_SUCCESS, got 0x%08x\n",
335 336 337
            GetLastError());
    }

338 339
    bDestroyed = DestroyWindow(hWnd);
    if (!bDestroyed)
340
        trace("Window %p couldn't be destroyed : 0x%08x\n",
341
            hWnd, GetLastError());
342 343
}

344 345 346 347 348 349 350 351 352 353 354 355 356 357
static void test_GetCurrentThemeName(void)
{
    BOOL    bThemeActive;
    HRESULT hRes;
    WCHAR currentTheme[MAX_PATH];
    WCHAR currentColor[MAX_PATH];
    WCHAR currentSize[MAX_PATH];

    bThemeActive = pIsThemeActive();

    /* All NULLs */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0);
    if (bThemeActive)
358
        ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
359
    else
360
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
361
    ok( GetLastError() == 0xdeadbeef,
362
        "Expected 0xdeadbeef, got 0x%08x\n",
363 364 365 366 367 368
        GetLastError());

    /* Number of characters given is 0 */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0);
    if (bThemeActive)
369
        ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
370
    else
371
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
372
    ok( GetLastError() == 0xdeadbeef,
373
        "Expected 0xdeadbeef, got 0x%08x\n",
374 375 376 377 378 379 380 381 382 383 384
        GetLastError());

    /* When the number of characters given is too small (not 0, see above), GetCurrentThemeName returns 0x8007007a.
     * The only definition I found was in strsafe.h:
     *
     * #define STRSAFE_E_INSUFFICIENT_BUFFER       ((HRESULT)0x8007007AL)  // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
     */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0);
    if (bThemeActive)
        todo_wine
385
            ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes);
386
    else
387
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
388
    ok( GetLastError() == 0xdeadbeef,
389
        "Expected 0xdeadbeef, got 0x%08x\n",
390 391 392 393 394 395 396 397 398
        GetLastError());

    /* The same is true if the number of characters is too small for Color and/or Size */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
                                currentColor, 2,
                                currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
    if (bThemeActive)
        todo_wine
399
            ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes);
400
    else
401
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
402
    ok( GetLastError() == 0xdeadbeef,
403
        "Expected 0xdeadbeef, got 0x%08x\n",
404 405 406 407 408 409
        GetLastError());

    /* Given number of characters is correct */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0);
    if (bThemeActive)
410
        ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
411
    else
412
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
413
    ok( GetLastError() == 0xdeadbeef,
414
        "Expected 0xdeadbeef, got 0x%08x\n",
415 416 417 418 419 420
        GetLastError());

    /* Given number of characters for the theme name is too large */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0);
    todo_wine
421
        ok( hRes == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hRes);
422
    ok( GetLastError() == 0xdeadbeef,
423
        "Expected 0xdeadbeef, got 0x%08x\n",
424 425 426 427 428 429 430 431
        GetLastError());
 
    /* The too large case is only for the theme name, not for color name or size name */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
                                currentColor, sizeof(currentTheme),
                                currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
    if (bThemeActive)
432
        ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
433
    else
434
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
435
    ok( GetLastError() == 0xdeadbeef,
436
        "Expected 0xdeadbeef, got 0x%08x\n",
437 438 439 440 441 442 443
        GetLastError());

    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
                                currentColor, sizeof(currentTheme) / sizeof(WCHAR),
                                currentSize,  sizeof(currentSize));
    if (bThemeActive)
444
        ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
445
    else
446
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
447
    ok( GetLastError() == 0xdeadbeef,
448
        "Expected 0xdeadbeef, got 0x%08x\n",
449 450 451 452 453 454 455 456
        GetLastError());

    /* Correct call */
    SetLastError(0xdeadbeef);
    hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 
                                currentColor, sizeof(currentColor) / sizeof(WCHAR),
                                currentSize,  sizeof(currentSize)  / sizeof(WCHAR));
    if (bThemeActive)
457
        ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes);
458
    else
459
        ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
460
    ok( GetLastError() == 0xdeadbeef,
461
        "Expected 0xdeadbeef, got 0x%08x\n",
462 463 464
        GetLastError());
}

465 466 467 468 469 470
static void test_CloseThemeData(void)
{
    HRESULT hRes;

    SetLastError(0xdeadbeef);
    hRes = pCloseThemeData(NULL);
471
    ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes);
472
    ok( GetLastError() == 0xdeadbeef,
473
        "Expected 0xdeadbeef, got 0x%08x\n",
474 475 476 477 478 479 480 481 482 483 484 485
        GetLastError());
}

START_TEST(system)
{
    if(!InitFunctionPtrs())
        return;

    /* No real functional tests will be done (yet). The current tests
     * only show input/return behaviour
     */

486
    /* IsThemeActive, IsAppThemed and IsThemePartDefined*/
487
    trace("Starting test_IsThemed()\n");
488
    test_IsThemed();
489

490 491
    /* GetWindowTheme */
    trace("Starting test_GetWindowTheme()\n");
492
    test_GetWindowTheme();
493

494 495
    /* SetWindowTheme */
    trace("Starting test_SetWindowTheme()\n");
496
    test_SetWindowTheme();
497

498
    /* OpenThemeData, a bit more functional now */
499
    trace("Starting test_OpenThemeData()\n");
500
    test_OpenThemeData();
501

502 503 504 505
    /* GetCurrentThemeName */
    trace("Starting test_GetCurrentThemeName()\n");
    test_GetCurrentThemeName();

506 507
    /* CloseThemeData */
    trace("Starting test_CloseThemeData()\n");
508
    test_CloseThemeData();
509 510 511

    FreeLibrary(hUxtheme);
}