| 3721 | |
| 3722 | |
| 3723 | ResultType Line::WinGetText(char *aTitle, char *aText, char *aExcludeTitle, char *aExcludeText) |
| 3724 | { |
| 3725 | Var *output_var = ResolveVarOfArg(0); |
| 3726 | if (!output_var) |
| 3727 | return FAIL; |
| 3728 | g_ErrorLevel->Assign(ERRORLEVEL_ERROR); // Set default ErrorLevel. |
| 3729 | HWND target_window = DetermineTargetWindow(aTitle, aText, aExcludeTitle, aExcludeText); |
| 3730 | // Even if target_window is NULL, we want to continue on so that the output |
| 3731 | // variables are set to be the empty string, which is the proper thing to do |
| 3732 | // rather than leaving whatever was in there before: |
| 3733 | if (!target_window) |
| 3734 | return output_var->Assign(); // Tell it not to free the memory by not calling with "". |
| 3735 | |
| 3736 | length_and_buf_type sab; |
| 3737 | sab.buf = NULL; // Tell it just to calculate the length this time around. |
| 3738 | sab.total_length = sab.capacity = 0; // Init |
| 3739 | EnumChildWindows(target_window, EnumChildGetText, (LPARAM)&sab); |
| 3740 | |
| 3741 | if (!sab.total_length) // No text in window. |
| 3742 | { |
| 3743 | g_ErrorLevel->Assign(ERRORLEVEL_NONE); // Indicate success. |
| 3744 | return output_var->Assign(); // Tell it not to free the memory by omitting all params. |
| 3745 | } |
| 3746 | // This adjustment was added because someone reported that max variable capacity was being |
| 3747 | // exceeded in some cases (perhaps custom controls that retrieve large amounts of text |
| 3748 | // from the disk in response to the "get text" message): |
| 3749 | if (sab.total_length >= g_MaxVarCapacity) // Allow the command to succeed by truncating the text. |
| 3750 | sab.total_length = g_MaxVarCapacity - 1; // And this length will be used to limit the retrieval capacity below. |
| 3751 | |
| 3752 | // Set up the var, enlarging it if necessary. If the output_var is of type VAR_CLIPBOARD, |
| 3753 | // this call will set up the clipboard for writing: |
| 3754 | if (output_var->Assign(NULL, (VarSizeType)sab.total_length) != OK) |
| 3755 | return FAIL; // It already displayed the error. |
| 3756 | |
| 3757 | // Fetch the text directly into the var. Also set the length explicitly |
| 3758 | // in case actual size written was off from the esimated size (since |
| 3759 | // GetWindowTextLength() can return more space that will actually be required |
| 3760 | // in certain circumstances, see MSDN): |
| 3761 | sab.buf = output_var->Contents(); |
| 3762 | sab.total_length = 0; // Init |
| 3763 | // Note: The capacity member below exists because granted capacity might be a little larger than we asked for, |
| 3764 | // which allows the actual text fetched to be larger than the length estimate retrieved by the first pass |
| 3765 | // (which generally shouldn't happen since MSDN docs say that the actual length can be less, but never greater, |
| 3766 | // than the estimate length): |
| 3767 | sab.capacity = output_var->Capacity(); // Capacity includes the zero terminator, i.e. it's the size of the memory area. |
| 3768 | EnumChildWindows(target_window, EnumChildGetText, (LPARAM)&sab); // Get the text. |
| 3769 | |
| 3770 | // Length is set explicitly below in case it wound up being smaller than expected/estimated. |
| 3771 | // MSDN says that can happen generally, and also specifically because: "ANSI applications may have |
| 3772 | // the string in the buffer reduced in size (to a minimum of half that of the wParam value) due to |
| 3773 | // conversion from ANSI to Unicode." |
| 3774 | output_var->Length() = (VarSizeType)sab.total_length; |
| 3775 | if (sab.total_length) |
| 3776 | g_ErrorLevel->Assign(ERRORLEVEL_NONE); // Indicate success. |
| 3777 | else |
| 3778 | // Something went wrong, so make sure we set to empty string. |
| 3779 | *output_var->Contents() = '\0'; // Safe because Assign() gave us a non-constant memory area. |
| 3780 | return output_var->Close(); // In case it's the clipboard. |