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 HTHEME (WINAPI * pOpenThemeDataEx)(HWND, LPCWSTR, DWORD); 30 static HPAINTBUFFER (WINAPI *pBeginBufferedPaint)(HDC, const RECT *, BP_BUFFERFORMAT, BP_PAINTPARAMS *, HDC *); 31 static HRESULT (WINAPI *pBufferedPaintClear)(HPAINTBUFFER, const RECT *); 32 static HRESULT (WINAPI *pEndBufferedPaint)(HPAINTBUFFER, BOOL); 33 static HRESULT (WINAPI *pGetBufferedPaintBits)(HPAINTBUFFER, RGBQUAD **, int *); 34 static HDC (WINAPI *pGetBufferedPaintDC)(HPAINTBUFFER); 35 static HDC (WINAPI *pGetBufferedPaintTargetDC)(HPAINTBUFFER); 36 static HRESULT (WINAPI *pGetBufferedPaintTargetRect)(HPAINTBUFFER, RECT *); 37 38 static void init_funcs(void) 39 { 40 HMODULE hUxtheme = GetModuleHandleA("uxtheme.dll"); 41 42 #define UXTHEME_GET_PROC(func) p ## func = (void*)GetProcAddress(hUxtheme, #func) 43 UXTHEME_GET_PROC(BeginBufferedPaint); 44 UXTHEME_GET_PROC(BufferedPaintClear); 45 UXTHEME_GET_PROC(EndBufferedPaint); 46 UXTHEME_GET_PROC(GetBufferedPaintBits); 47 UXTHEME_GET_PROC(GetBufferedPaintDC); 48 UXTHEME_GET_PROC(GetBufferedPaintTargetDC); 49 UXTHEME_GET_PROC(GetBufferedPaintTargetRect); 50 UXTHEME_GET_PROC(BufferedPaintClear); 51 52 UXTHEME_GET_PROC(OpenThemeDataEx); 53 #undef UXTHEME_GET_PROC 54 } 55 56 static void test_IsThemed(void) 57 { 58 BOOL bThemeActive; 59 BOOL bAppThemed; 60 BOOL bTPDefined; 61 62 bThemeActive = IsThemeActive(); 63 trace("Theming is %s\n", (bThemeActive) ? "active" : "inactive"); 64 65 bAppThemed = IsAppThemed(); 66 trace("Test executable is %s\n", (bAppThemed) ? "themed" : "not themed"); 67 68 SetLastError(0xdeadbeef); 69 bTPDefined = IsThemePartDefined(NULL, 0 , 0); 70 ok( bTPDefined == FALSE, "Expected FALSE\n"); 71 ok( GetLastError() == E_HANDLE, 72 "Expected E_HANDLE, got 0x%08x\n", 73 GetLastError()); 74 } 75 76 static void test_GetWindowTheme(void) 77 { 78 HTHEME hTheme; 79 HWND hWnd; 80 BOOL bDestroyed; 81 82 SetLastError(0xdeadbeef); 83 hTheme = GetWindowTheme(NULL); 84 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 85 todo_wine 86 ok( GetLastError() == E_HANDLE, 87 "Expected E_HANDLE, got 0x%08x\n", 88 GetLastError()); 89 90 /* Only do the bare minimum to get a valid hwnd */ 91 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL); 92 if (!hWnd) return; 93 94 SetLastError(0xdeadbeef); 95 hTheme = GetWindowTheme(hWnd); 96 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 97 ok( GetLastError() == 0xdeadbeef, 98 "Expected 0xdeadbeef, got 0x%08x\n", 99 GetLastError()); 100 101 bDestroyed = DestroyWindow(hWnd); 102 if (!bDestroyed) 103 trace("Window %p couldn't be destroyed : 0x%08x\n", 104 hWnd, GetLastError()); 105 } 106 107 static void test_SetWindowTheme(void) 108 { 109 HRESULT hRes; 110 HWND hWnd; 111 BOOL bDestroyed; 112 113 hRes = SetWindowTheme(NULL, NULL, NULL); 114 todo_wine 115 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes); 116 117 /* Only do the bare minimum to get a valid hwnd */ 118 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL); 119 if (!hWnd) return; 120 121 hRes = SetWindowTheme(hWnd, NULL, NULL); 122 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 123 124 bDestroyed = DestroyWindow(hWnd); 125 if (!bDestroyed) 126 trace("Window %p couldn't be destroyed : 0x%08x\n", 127 hWnd, GetLastError()); 128 } 129 130 static void test_OpenThemeData(void) 131 { 132 HTHEME hTheme, hTheme2; 133 HWND hWnd; 134 BOOL bThemeActive; 135 HRESULT hRes; 136 BOOL bDestroyed; 137 BOOL bTPDefined; 138 139 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 }; 140 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 }; 141 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 }; 142 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 }; 143 144 bThemeActive = IsThemeActive(); 145 146 /* All NULL */ 147 SetLastError(0xdeadbeef); 148 hTheme = OpenThemeData(NULL, NULL); 149 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 150 ok( GetLastError() == E_POINTER, 151 "Expected GLE() to be E_POINTER, got 0x%08x\n", 152 GetLastError()); 153 154 /* A NULL hWnd and an invalid classlist */ 155 SetLastError(0xdeadbeef); 156 hTheme = OpenThemeData(NULL, szInvalidClassList); 157 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 158 todo_wine 159 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 160 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 161 GetLastError()); 162 163 SetLastError(0xdeadbeef); 164 hTheme = OpenThemeData(NULL, szClassList); 165 if (bThemeActive) 166 { 167 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 168 todo_wine 169 ok( GetLastError() == ERROR_SUCCESS, 170 "Expected ERROR_SUCCESS, got 0x%08x\n", 171 GetLastError()); 172 } 173 else 174 { 175 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 176 todo_wine 177 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 178 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 179 GetLastError()); 180 } 181 182 /* Only do the bare minimum to get a valid hdc */ 183 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL); 184 if (!hWnd) return; 185 186 SetLastError(0xdeadbeef); 187 hTheme = OpenThemeData(hWnd, NULL); 188 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 189 ok( GetLastError() == E_POINTER, 190 "Expected GLE() to be E_POINTER, got 0x%08x\n", 191 GetLastError()); 192 193 SetLastError(0xdeadbeef); 194 hTheme = OpenThemeData(hWnd, szInvalidClassList); 195 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 196 todo_wine 197 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 198 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 199 GetLastError()); 200 201 /* Close invalid handle */ 202 hRes = CloseThemeData((HTHEME)0xdeadbeef); 203 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes); 204 205 if (!bThemeActive) 206 { 207 SetLastError(0xdeadbeef); 208 hTheme = OpenThemeData(hWnd, szButtonClassList); 209 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 210 todo_wine 211 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 212 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 213 GetLastError()); 214 skip("No active theme, skipping rest of OpenThemeData tests\n"); 215 return; 216 } 217 218 /* Only do the next checks if we have an active theme */ 219 220 SetLastError(0xdeadbeef); 221 hTheme = OpenThemeData(hWnd, szButtonClassList); 222 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 223 todo_wine 224 ok( GetLastError() == ERROR_SUCCESS, 225 "Expected ERROR_SUCCESS, got 0x%08x\n", 226 GetLastError()); 227 228 /* Test with bUtToN instead of Button */ 229 SetLastError(0xdeadbeef); 230 hTheme = OpenThemeData(hWnd, szButtonClassList2); 231 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 232 todo_wine 233 ok( GetLastError() == ERROR_SUCCESS, 234 "Expected ERROR_SUCCESS, got 0x%08x\n", 235 GetLastError()); 236 237 SetLastError(0xdeadbeef); 238 hTheme = OpenThemeData(hWnd, szClassList); 239 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 240 todo_wine 241 ok( GetLastError() == ERROR_SUCCESS, 242 "Expected ERROR_SUCCESS, got 0x%08x\n", 243 GetLastError()); 244 245 /* GetWindowTheme should return the last handle opened by OpenThemeData */ 246 SetLastError(0xdeadbeef); 247 hTheme2 = GetWindowTheme(hWnd); 248 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n", 249 hTheme, hTheme2); 250 ok( GetLastError() == 0xdeadbeef, 251 "Expected 0xdeadbeef, got 0x%08x\n", 252 GetLastError()); 253 254 hRes = CloseThemeData(hTheme); 255 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 256 257 /* Close a second time */ 258 hRes = CloseThemeData(hTheme); 259 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 260 261 /* See if closing makes a difference for GetWindowTheme */ 262 SetLastError(0xdeadbeef); 263 hTheme2 = NULL; 264 hTheme2 = GetWindowTheme(hWnd); 265 ok( hTheme == hTheme2, "Expected the same HTHEME handle (%p<->%p)\n", 266 hTheme, hTheme2); 267 ok( GetLastError() == 0xdeadbeef, 268 "Expected 0xdeadbeef, got 0x%08x\n", 269 GetLastError()); 270 271 SetLastError(0xdeadbeef); 272 bTPDefined = IsThemePartDefined(hTheme, 0 , 0); 273 todo_wine 274 { 275 ok( bTPDefined == FALSE, "Expected FALSE\n"); 276 ok( GetLastError() == ERROR_SUCCESS, 277 "Expected ERROR_SUCCESS, got 0x%08x\n", 278 GetLastError()); 279 } 280 281 bDestroyed = DestroyWindow(hWnd); 282 if (!bDestroyed) 283 trace("Window %p couldn't be destroyed : 0x%08x\n", 284 hWnd, GetLastError()); 285 } 286 287 static void test_OpenThemeDataEx(void) 288 { 289 HTHEME hTheme; 290 HWND hWnd; 291 BOOL bThemeActive; 292 BOOL bDestroyed; 293 294 WCHAR szInvalidClassList[] = {'D','E','A','D','B','E','E','F', 0 }; 295 WCHAR szButtonClassList[] = {'B','u','t','t','o','n', 0 }; 296 WCHAR szButtonClassList2[] = {'b','U','t','T','o','N', 0 }; 297 WCHAR szClassList[] = {'B','u','t','t','o','n',';','L','i','s','t','B','o','x', 0 }; 298 299 if (!pOpenThemeDataEx) 300 { 301 win_skip("OpenThemeDataEx not available\n"); 302 return; 303 } 304 305 bThemeActive = IsThemeActive(); 306 307 /* All NULL */ 308 SetLastError(0xdeadbeef); 309 hTheme = pOpenThemeDataEx(NULL, NULL, 0); 310 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 311 ok( GetLastError() == E_POINTER, 312 "Expected GLE() to be E_POINTER, got 0x%08x\n", 313 GetLastError()); 314 315 /* A NULL hWnd and an invalid classlist without flags */ 316 SetLastError(0xdeadbeef); 317 hTheme = pOpenThemeDataEx(NULL, szInvalidClassList, 0); 318 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 319 todo_wine 320 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 321 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 322 GetLastError()); 323 324 SetLastError(0xdeadbeef); 325 hTheme = pOpenThemeDataEx(NULL, szClassList, 0); 326 if (bThemeActive) 327 { 328 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 329 todo_wine 330 ok( GetLastError() == ERROR_SUCCESS, 331 "Expected ERROR_SUCCESS, got 0x%08x\n", 332 GetLastError()); 333 } 334 else 335 { 336 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 337 todo_wine 338 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 339 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 340 GetLastError()); 341 } 342 343 /* Only do the bare minimum to get a valid hdc */ 344 hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL); 345 if (!hWnd) return; 346 347 SetLastError(0xdeadbeef); 348 hTheme = pOpenThemeDataEx(hWnd, NULL, 0); 349 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 350 ok( GetLastError() == E_POINTER, 351 "Expected GLE() to be E_POINTER, got 0x%08x\n", 352 GetLastError()); 353 354 SetLastError(0xdeadbeef); 355 hTheme = pOpenThemeDataEx(hWnd, szInvalidClassList, 0); 356 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 357 todo_wine 358 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 359 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 360 GetLastError()); 361 362 if (!bThemeActive) 363 { 364 SetLastError(0xdeadbeef); 365 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, 0); 366 ok( hTheme == NULL, "Expected a NULL return, got %p\n", hTheme); 367 todo_wine 368 ok( GetLastError() == E_PROP_ID_UNSUPPORTED, 369 "Expected GLE() to be E_PROP_ID_UNSUPPORTED, got 0x%08x\n", 370 GetLastError()); 371 skip("No active theme, skipping rest of OpenThemeDataEx tests\n"); 372 return; 373 } 374 375 /* Only do the next checks if we have an active theme */ 376 377 SetLastError(0xdeadbeef); 378 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, 0); 379 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 380 todo_wine 381 ok( GetLastError() == ERROR_SUCCESS, 382 "Expected ERROR_SUCCESS, got 0x%08x\n", 383 GetLastError()); 384 385 SetLastError(0xdeadbeef); 386 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, OTD_FORCE_RECT_SIZING); 387 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 388 todo_wine 389 ok( GetLastError() == ERROR_SUCCESS, 390 "Expected ERROR_SUCCESS, got 0x%08x\n", 391 GetLastError()); 392 393 SetLastError(0xdeadbeef); 394 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, OTD_NONCLIENT); 395 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 396 todo_wine 397 ok( GetLastError() == ERROR_SUCCESS, 398 "Expected ERROR_SUCCESS, got 0x%08x\n", 399 GetLastError()); 400 401 SetLastError(0xdeadbeef); 402 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList, 0x3); 403 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 404 todo_wine 405 ok( GetLastError() == ERROR_SUCCESS, 406 "Expected ERROR_SUCCESS, got 0x%08x\n", 407 GetLastError()); 408 409 /* Test with bUtToN instead of Button */ 410 SetLastError(0xdeadbeef); 411 hTheme = pOpenThemeDataEx(hWnd, szButtonClassList2, 0); 412 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 413 todo_wine 414 ok( GetLastError() == ERROR_SUCCESS, 415 "Expected ERROR_SUCCESS, got 0x%08x\n", 416 GetLastError()); 417 418 SetLastError(0xdeadbeef); 419 hTheme = pOpenThemeDataEx(hWnd, szClassList, 0); 420 ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); 421 todo_wine 422 ok( GetLastError() == ERROR_SUCCESS, 423 "Expected ERROR_SUCCESS, got 0x%08x\n", 424 GetLastError()); 425 426 bDestroyed = DestroyWindow(hWnd); 427 if (!bDestroyed) 428 trace("Window %p couldn't be destroyed : 0x%08x\n", 429 hWnd, GetLastError()); 430 } 431 432 static void test_GetCurrentThemeName(void) 433 { 434 BOOL bThemeActive; 435 HRESULT hRes; 436 WCHAR currentTheme[MAX_PATH]; 437 WCHAR currentColor[MAX_PATH]; 438 WCHAR currentSize[MAX_PATH]; 439 440 bThemeActive = IsThemeActive(); 441 442 /* All NULLs */ 443 hRes = GetCurrentThemeName(NULL, 0, NULL, 0, NULL, 0); 444 if (bThemeActive) 445 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 446 else 447 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 448 449 /* Number of characters given is 0 */ 450 hRes = GetCurrentThemeName(currentTheme, 0, NULL, 0, NULL, 0); 451 if (bThemeActive) 452 ok( hRes == S_OK || broken(hRes == E_FAIL /* WinXP SP1 */), "Expected S_OK, got 0x%08x\n", hRes); 453 else 454 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 455 456 hRes = GetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0); 457 if (bThemeActive) 458 todo_wine 459 ok(hRes == E_NOT_SUFFICIENT_BUFFER || 460 broken(hRes == E_FAIL /* WinXP SP1 */), 461 "Expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hRes); 462 else 463 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 464 465 /* The same is true if the number of characters is too small for Color and/or Size */ 466 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 467 currentColor, 2, 468 currentSize, sizeof(currentSize) / sizeof(WCHAR)); 469 if (bThemeActive) 470 todo_wine 471 ok(hRes == E_NOT_SUFFICIENT_BUFFER || 472 broken(hRes == E_FAIL /* WinXP SP1 */), 473 "Expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hRes); 474 else 475 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 476 477 /* Given number of characters is correct */ 478 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), NULL, 0, NULL, 0); 479 if (bThemeActive) 480 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 481 else 482 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 483 484 /* Given number of characters for the theme name is too large */ 485 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0); 486 if (bThemeActive) 487 ok( hRes == E_POINTER || hRes == S_OK, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes); 488 else 489 ok( hRes == E_PROP_ID_UNSUPPORTED || 490 hRes == E_POINTER, /* win2k3 */ 491 "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 492 493 /* The too large case is only for the theme name, not for color name or size name */ 494 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 495 currentColor, sizeof(currentTheme), 496 currentSize, sizeof(currentSize) / sizeof(WCHAR)); 497 if (bThemeActive) 498 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 499 else 500 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 501 502 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 503 currentColor, sizeof(currentTheme) / sizeof(WCHAR), 504 currentSize, sizeof(currentSize)); 505 if (bThemeActive) 506 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 507 else 508 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 509 510 /* Correct call */ 511 hRes = GetCurrentThemeName(currentTheme, sizeof(currentTheme) / sizeof(WCHAR), 512 currentColor, sizeof(currentColor) / sizeof(WCHAR), 513 currentSize, sizeof(currentSize) / sizeof(WCHAR)); 514 if (bThemeActive) 515 ok( hRes == S_OK, "Expected S_OK, got 0x%08x\n", hRes); 516 else 517 ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); 518 } 519 520 static void test_CloseThemeData(void) 521 { 522 HRESULT hRes; 523 524 hRes = CloseThemeData(NULL); 525 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes); 526 hRes = CloseThemeData(INVALID_HANDLE_VALUE); 527 ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes); 528 } 529 530 static void test_buffer_dc_props(HDC hdc, const RECT *rect) 531 { 532 static const XFORM ident = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }; 533 XFORM xform; 534 POINT org; 535 RECT box; 536 BOOL ret; 537 538 ret = GetWorldTransform(hdc, &xform); 539 ok(ret, "Failed to get world transform\n"); 540 ok(!memcmp(&xform, &ident, sizeof(xform)), "Unexpected world transform\n"); 541 542 ret = GetViewportOrgEx(hdc, &org); 543 ok(ret, "Failed to get vport origin\n"); 544 ok(org.x == 0 && org.y == 0, "Unexpected vport origin\n"); 545 546 ret = GetWindowOrgEx(hdc, &org); 547 ok(ret, "Failed to get vport origin\n"); 548 ok(org.x == rect->left && org.y == rect->top, "Unexpected window origin\n"); 549 550 ret = GetClipBox(hdc, &box); 551 ok(ret, "Failed to get clip box\n"); 552 ok(box.left == rect->left && box.top == rect->top, "Unexpected clip box\n"); 553 554 ok(GetGraphicsMode(hdc) == GM_COMPATIBLE, "wrong graphics mode\n"); 555 } 556 557 static void test_buffered_paint(void) 558 { 559 HDC target, src, hdc, screen_dc; 560 BP_PAINTPARAMS params = { 0 }; 561 BP_BUFFERFORMAT format; 562 HPAINTBUFFER buffer; 563 RECT rect, rect2; 564 RGBQUAD *bits; 565 HBITMAP hbm; 566 HRESULT hr; 567 int row; 568 569 if (!pBeginBufferedPaint) 570 { 571 win_skip("Buffered painting API is not supported.\n"); 572 return; 573 } 574 575 buffer = pBeginBufferedPaint(NULL, NULL, BPBF_COMPATIBLEBITMAP, 576 NULL, NULL); 577 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 578 579 target = CreateCompatibleDC(0); 580 buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP, 581 NULL, NULL); 582 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 583 584 params.cbSize = sizeof(params); 585 buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP, 586 ¶ms, NULL); 587 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 588 589 src = (void *)0xdeadbeef; 590 buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP, 591 ¶ms, &src); 592 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 593 ok(src == NULL, "Unexpected buffered dc %p\n", src); 594 595 /* target rect is mandatory */ 596 SetRectEmpty(&rect); 597 src = (void *)0xdeadbeef; 598 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP, 599 ¶ms, &src); 600 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 601 ok(src == NULL, "Unexpected buffered dc %p\n", src); 602 603 /* inverted rectangle */ 604 SetRect(&rect, 10, 0, 5, 5); 605 src = (void *)0xdeadbeef; 606 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP, 607 ¶ms, &src); 608 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 609 ok(src == NULL, "Unexpected buffered dc %p\n", src); 610 611 SetRect(&rect, 0, 10, 5, 0); 612 src = (void *)0xdeadbeef; 613 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP, 614 ¶ms, &src); 615 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 616 ok(src == NULL, "Unexpected buffered dc %p\n", src); 617 618 /* valid rectangle, no target dc */ 619 SetRect(&rect, 0, 0, 5, 5); 620 src = (void *)0xdeadbeef; 621 buffer = pBeginBufferedPaint(NULL, &rect, BPBF_COMPATIBLEBITMAP, 622 ¶ms, &src); 623 ok(buffer == NULL, "Unexpected buffer %p\n", buffer); 624 ok(src == NULL, "Unexpected buffered dc %p\n", src); 625 626 SetRect(&rect, 0, 0, 5, 5); 627 src = NULL; 628 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP, 629 ¶ms, &src); 630 ok(buffer != NULL, "Unexpected buffer %p\n", buffer); 631 ok(src != NULL, "Expected buffered dc\n"); 632 hr = pEndBufferedPaint(buffer, FALSE); 633 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 634 635 SetRect(&rect, 0, 0, 5, 5); 636 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP, 637 ¶ms, &src); 638 ok(buffer != NULL, "Unexpected buffer %p\n", buffer); 639 640 /* clearing */ 641 hr = pBufferedPaintClear(NULL, NULL); 642 todo_wine 643 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr); 644 645 hr = pBufferedPaintClear(buffer, NULL); 646 todo_wine 647 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 648 649 /* access buffer attributes */ 650 hdc = pGetBufferedPaintDC(buffer); 651 ok(hdc == src, "Unexpected hdc, %p, buffered dc %p\n", hdc, src); 652 653 hdc = pGetBufferedPaintTargetDC(buffer); 654 ok(hdc == target, "Unexpected target hdc %p, original %p\n", hdc, target); 655 656 hr = pGetBufferedPaintTargetRect(NULL, NULL); 657 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr); 658 659 hr = pGetBufferedPaintTargetRect(buffer, NULL); 660 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr); 661 662 hr = pGetBufferedPaintTargetRect(NULL, &rect2); 663 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr); 664 665 SetRectEmpty(&rect2); 666 hr = pGetBufferedPaintTargetRect(buffer, &rect2); 667 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 668 ok(EqualRect(&rect, &rect2), "Wrong target rect\n"); 669 670 hr = pEndBufferedPaint(buffer, FALSE); 671 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 672 673 /* invalid buffer handle */ 674 hr = pEndBufferedPaint(NULL, FALSE); 675 ok(hr == E_INVALIDARG, "Unexpected return code %#x\n", hr); 676 677 hdc = pGetBufferedPaintDC(NULL); 678 ok(hdc == NULL, "Unexpected hdc %p\n", hdc); 679 680 hdc = pGetBufferedPaintTargetDC(NULL); 681 ok(hdc == NULL, "Unexpected target hdc %p\n", hdc); 682 683 hr = pGetBufferedPaintTargetRect(NULL, &rect2); 684 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr); 685 686 hr = pGetBufferedPaintTargetRect(NULL, NULL); 687 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr); 688 689 bits = (void *)0xdeadbeef; 690 row = 10; 691 hr = pGetBufferedPaintBits(NULL, &bits, &row); 692 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr); 693 ok(row == 10, "Unexpected row count %d\n", row); 694 ok(bits == (void *)0xdeadbeef, "Unepexpected data pointer %p\n", bits); 695 696 hr = pGetBufferedPaintBits(NULL, NULL, NULL); 697 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr); 698 699 hr = pGetBufferedPaintBits(NULL, &bits, NULL); 700 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr); 701 702 hr = pGetBufferedPaintBits(NULL, NULL, &row); 703 ok(hr == E_POINTER, "Unexpected return code %#x\n", hr); 704 705 screen_dc = GetDC(0); 706 707 hdc = CreateCompatibleDC(screen_dc); 708 ok(hdc != NULL, "Failed to create a DC\n"); 709 hbm = CreateCompatibleBitmap(screen_dc, 64, 64); 710 ok(hbm != NULL, "Failed to create a bitmap\n"); 711 SelectObject(hdc, hbm); 712 713 ReleaseDC(0, screen_dc); 714 715 SetRect(&rect, 1, 2, 34, 56); 716 717 buffer = pBeginBufferedPaint(hdc, &rect, BPBF_COMPATIBLEBITMAP, NULL, &src); 718 test_buffer_dc_props(src, &rect); 719 hr = pEndBufferedPaint(buffer, FALSE); 720 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 721 722 DeleteObject(hbm); 723 DeleteDC(hdc); 724 725 buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP, NULL, &src); 726 test_buffer_dc_props(src, &rect); 727 hr = pEndBufferedPaint(buffer, FALSE); 728 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 729 730 /* access buffer bits */ 731 for (format = BPBF_COMPATIBLEBITMAP; format <= BPBF_TOPDOWNMONODIB; format++) 732 { 733 buffer = pBeginBufferedPaint(target, &rect, format, ¶ms, &src); 734 735 /* only works for DIB buffers */ 736 bits = NULL; 737 row = 0; 738 hr = pGetBufferedPaintBits(buffer, &bits, &row); 739 if (format == BPBF_COMPATIBLEBITMAP) 740 ok(hr == E_FAIL, "Unexpected return code %#x\n", hr); 741 else 742 { 743 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 744 ok(bits != NULL, "Bitmap bits %p\n", bits); 745 ok(row >= (rect.right - rect.left), "format %d: bitmap width %d\n", format, row); 746 } 747 748 hr = pEndBufferedPaint(buffer, FALSE); 749 ok(hr == S_OK, "Unexpected return code %#x\n", hr); 750 } 751 752 DeleteDC(target); 753 } 754 755 START_TEST(system) 756 { 757 init_funcs(); 758 759 /* No real functional theme API tests will be done (yet). The current tests 760 * only show input/return behaviour 761 */ 762 763 test_IsThemed(); 764 test_GetWindowTheme(); 765 test_SetWindowTheme(); 766 test_OpenThemeData(); 767 test_OpenThemeDataEx(); 768 test_GetCurrentThemeName(); 769 test_CloseThemeData(); 770 test_buffered_paint(); 771 } 772