Текст из значения свойства UIAutomation усечен до 4k - PullRequest
1 голос
/ 04 октября 2019

Я использую UIAutomation из 32-разрядного приложения C ++ в Windows 7 для получения текстового содержимого окон других процессов. Я заметил, что API всегда возвращает строки, обрезанные до 4096 символов, если текст в окнах длиннее. Это происходит как с вызовами GetCachedPropertyValue (), так и с вызовами GetCurrentPropertyValue () для идентификаторов свойств UIA_ValueValuePropertyId и UIA_LegacyIAccessibleValuePropertyId. Протестировано, среди прочего, на 32- и 64-битном блокноте. Когда я получаю текст, используя SendMessage и сообщения WM_GETTEXTLENGTH и WM_GETTEXT, возвращается полный не усеченный текст. (Это я в настоящее время использую в качестве обходного пути.)

Просматривая документацию, я нигде не могу найти упоминания об этом ограничении или о том, как его обойти, чего я и ожидал бы, если бы усечение было разработано. Я обнаружил похожий вопрос в стеке, но его усечение, по-видимому, было связано с отладчиком Visual Studio, а не с API UIAutomation. Однако этот вопрос проясняет, что UIAutomation должна иметь возможность возвращать очень длинные тексты. Поиск этой проблемы приводит к другому вопросу в стеке, который также упоминает ограничение в 4096 символов, но, к сожалению, этот вопрос и любые возможные ответы удаляются.

Возможно, свойства UIA_ValueValuePropertyId или UIA_LegacyIAccessibleValuePropertyId не являются правильнымиодин для использования, но я не смог определить лучший.

Может кто-нибудь указать мне, что я делаю неправильно, или есть предложения, что я мог бы попробовать? Также приветствуются указатели на части документации, которые я явно пропустил.

TIA

1 Ответ

1 голос
/ 09 октября 2019

Описание значения приведено здесь для удобства, но имеет ограниченные возможности. Вместо этого вы должны использовать TextPattern , а это свойство DocumentRange . Это явно указано здесь . Из него вы можете использовать метод GetText(-1) для извлечения ваших данных.

Вы можете кодировать его так:

string GetText(AutomationElement ae)
{
    return (ae.GetCurrentPattern(TextPattern.Pattern) as TextPattern)?.DocumentRange.GetText(-1);
}   
...