| 2379 | |
| 2380 | |
| 2381 | void WinSetRegion(HWND aWnd, LPTSTR aPoints, ResultToken &aResultToken) |
| 2382 | { |
| 2383 | if (!*aPoints) // Attempt to restore the window's normal/correct region. |
| 2384 | { |
| 2385 | // Fix for v1.0.31.07: The old method used the following, but apparently it's not the correct |
| 2386 | // way to restore a window's proper/normal region because when such a window is later maximized, |
| 2387 | // it retains its incorrect/smaller region: |
| 2388 | //if (GetWindowRect(aWnd, &rect)) |
| 2389 | //{ |
| 2390 | // // Adjust the rect to keep the same size but have its upper-left corner at 0,0: |
| 2391 | // rect.right -= rect.left; |
| 2392 | // rect.bottom -= rect.top; |
| 2393 | // rect.left = 0; |
| 2394 | // rect.top = 0; |
| 2395 | // if (hrgn = CreateRectRgnIndirect(&rect)) // Assign |
| 2396 | // { |
| 2397 | // // Presumably, the system deletes the former region when upon a successful call to SetWindowRgn(). |
| 2398 | // if (SetWindowRgn(aWnd, hrgn, TRUE)) |
| 2399 | // _f_return_empty; |
| 2400 | // // Otherwise, get rid of it since it didn't take effect: |
| 2401 | // DeleteObject(hrgn); |
| 2402 | // } |
| 2403 | //} |
| 2404 | //// Since above didn't return: |
| 2405 | //return OK; |
| 2406 | |
| 2407 | // It's undocumented by MSDN, but apparently setting the Window's region to NULL restores it |
| 2408 | // to proper working order: |
| 2409 | if (!SetWindowRgn(aWnd, NULL, TRUE)) |
| 2410 | _f_throw_win32(); |
| 2411 | _f_return_empty; |
| 2412 | } |
| 2413 | |
| 2414 | #define MAX_REGION_POINTS 2000 // 2000 requires 16 KB of stack space. |
| 2415 | POINT pt[MAX_REGION_POINTS]; |
| 2416 | int pt_count; |
| 2417 | LPTSTR cp; |
| 2418 | |
| 2419 | // Set defaults prior to parsing options in case any options are absent: |
| 2420 | int width = COORD_UNSPECIFIED; |
| 2421 | int height = COORD_UNSPECIFIED; |
| 2422 | int rr_width = COORD_UNSPECIFIED; // These two are for the rounded-rectangle method. |
| 2423 | int rr_height = COORD_UNSPECIFIED; |
| 2424 | bool use_ellipse = false; |
| 2425 | |
| 2426 | int fill_mode = ALTERNATE; |
| 2427 | // Concerning polygon regions: ALTERNATE is used by default (somewhat arbitrarily, but it seems to be the |
| 2428 | // more typical default). |
| 2429 | // MSDN: "In general, the modes [ALTERNATE vs. WINDING] differ only in cases where a complex, |
| 2430 | // overlapping polygon must be filled (for example, a five-sided polygon that forms a five-pointed |
| 2431 | // star with a pentagon in the center). In such cases, ALTERNATE mode fills every other enclosed |
| 2432 | // region within the polygon (that is, the points of the star), but WINDING mode fills all regions |
| 2433 | // (that is, the points and the pentagon)." |
| 2434 | |
| 2435 | for (pt_count = 0, cp = aPoints; *(cp = omit_leading_whitespace(cp));) |
| 2436 | { |
| 2437 | // To allow the MAX to be increased in the future with less chance of breaking existing scripts, consider this an error. |
| 2438 | if (pt_count >= MAX_REGION_POINTS) |
no test coverage detected