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