| 3609 | |
| 3610 | |
| 3611 | ResultType Line::WinGetControlList(Var *aOutputVar, HWND aTargetWindow) |
| 3612 | // Caller must ensure that aOutputVar and aTargetWindow are non-NULL and valid. |
| 3613 | // Every control is fetched rather than just a list of distinct class names (possibly with a |
| 3614 | // second script array containing the quantity of each class) because it's conceivable that the |
| 3615 | // z-order of the controls will be useful information to some script authors. |
| 3616 | // A delimited list is used rather than the array technique used by "WinGet, OutputVar, List" because: |
| 3617 | // 1) It allows the flexibility of searching the list more easily with something like IfInString. |
| 3618 | // 2) It seems rather rare that the count of items in the list would be useful info to a script author |
| 3619 | // (the count can be derived with a parsing loop if it's ever needed). |
| 3620 | // 3) It saves memory since script arrays are permanent and since each array element would incur |
| 3621 | // the overhead of being a script variable, not to mention that each variable has a minimum |
| 3622 | // capacity (additional overhead) of 64 bytes. |
| 3623 | { |
| 3624 | control_list_type cl; // A big struct containing room to store class names and counts for each. |
| 3625 | CL_INIT_CONTROL_LIST(cl) |
| 3626 | cl.target_buf = NULL; // First pass: Signal it not not to write to the buf, but instead only calculate the length. |
| 3627 | EnumChildWindows(aTargetWindow, EnumChildGetControlList, (LPARAM)&cl); |
| 3628 | if (!cl.total_length) // No controls in the window. |
| 3629 | return aOutputVar->Assign(); |
| 3630 | // This adjustment was added because someone reported that max variable capacity was being |
| 3631 | // exceeded in some cases (perhaps custom controls that retrieve large amounts of text |
| 3632 | // from the disk in response to the "get text" message): |
| 3633 | if (cl.total_length >= g_MaxVarCapacity) // Allow the command to succeed by truncating the text. |
| 3634 | cl.total_length = g_MaxVarCapacity - 1; |
| 3635 | // Set up the var, enlarging it if necessary. If the aOutputVar is of type VAR_CLIPBOARD, |
| 3636 | // this call will set up the clipboard for writing: |
| 3637 | if (aOutputVar->Assign(NULL, (VarSizeType)cl.total_length) != OK) |
| 3638 | return FAIL; // It already displayed the error. |
| 3639 | // Fetch the text directly into the var. Also set the length explicitly |
| 3640 | // in case actual size written was off from the esimated size (in case the list of |
| 3641 | // controls changed in the split second between pass #1 and pass #2): |
| 3642 | CL_INIT_CONTROL_LIST(cl) |
| 3643 | cl.target_buf = aOutputVar->Contents(); // Second pass: Write to the buffer. |
| 3644 | cl.capacity = aOutputVar->Capacity(); // Because granted capacity might be a little larger than we asked for. |
| 3645 | EnumChildWindows(aTargetWindow, EnumChildGetControlList, (LPARAM)&cl); |
| 3646 | aOutputVar->Length() = (VarSizeType)cl.total_length; // In case it wound up being smaller than expected. |
| 3647 | if (!cl.total_length) // Something went wrong, so make sure its terminated just in case. |
| 3648 | *aOutputVar->Contents() = '\0'; // Safe because Assign() gave us a non-constant memory area. |
| 3649 | return aOutputVar->Close(); // In case it's the clipboard. |
| 3650 | } |
| 3651 | |
| 3652 | |
| 3653 | |