Как получить слово под курсором в Windows?
Я хочу создать приложение, которое получает слово под курсором (не только для текстовых полей), но я не могу найти, как это сделать. Использование OCR довольно сложно. Единственное, что я видел в работе - это компоненты Deskperience. Они поддерживают "родной" путь, но я стою дорого. Теперь я пытаюсь выяснить, что это за "родной" способ (возможно, каким-то образом зацепить). Любая помощь будет оценена.
РЕДАКТИРОВАТЬ: Я нашел способ, но он получает только весь текст элемента управления. Любая идея, как получить только слово под курсором из всего текста?
6 ответов
В последних версиях Windows рекомендуемым способом сбора информации из одного приложения в другое (если вы, конечно, не являетесь владельцем целевого приложения) является использование технологии автоматизации пользовательского интерфейса. Википедия довольно хороша для получения дополнительной информации об этом: Microsoft UI Automation
В основном, автоматизация пользовательского интерфейса будет использовать все необходимые средства, чтобы собрать то, что можно собрать
Вот небольшой код консольного приложения, который будет следить за пользовательским интерфейсом других приложений. Запустите его и наведите курсор мыши на разные приложения. Каждое приложение имеет различную поддержку различных "шаблонов автоматизации пользовательского интерфейса". Например, есть шаблон Value и текстовый шаблон, как показано здесь.
static void Main(string[] args)
{
do
{
System.Drawing.Point mouse = System.Windows.Forms.Cursor.Position; // use Windows forms mouse code instead of WPF
AutomationElement element = AutomationElement.FromPoint(new System.Windows.Point(mouse.X, mouse.Y));
if (element == null)
{
// no element under mouse
return;
}
Console.WriteLine("Element at position " + mouse + " is '" + element.Current.Name + "'");
object pattern;
// the "Value" pattern is supported by many application (including IE & FF)
if (element.TryGetCurrentPattern(ValuePattern.Pattern, out pattern))
{
ValuePattern valuePattern = (ValuePattern)pattern;
Console.WriteLine(" Value=" + valuePattern.Current.Value);
}
// the "Text" pattern is supported by some applications (including Notepad)and returns the current selection for example
if (element.TryGetCurrentPattern(TextPattern.Pattern, out pattern))
{
TextPattern textPattern = (TextPattern)pattern;
foreach(TextPatternRange range in textPattern.GetSelection())
{
Console.WriteLine(" SelectionRange=" + range.GetText(-1));
}
}
Thread.Sleep(1000);
Console.WriteLine(); Console.WriteLine();
}
while (true);
}
Автоматизация пользовательского интерфейса фактически поддерживается Internet Explorer и Firefox, но не Chrome, насколько мне известно. Посмотрите эту ссылку: Когда будет доступен Google Chrome?
Теперь это только начало работы для вас:-), потому что:
В большинстве случаев все это имеет серьезные последствия для безопасности. Использование этой технологии (или прямой технологии Windows, такой как WindowFromPoint) потребует достаточных прав для этого (например, администратор). И я не думаю, что DExperience каким-либо образом преодолеет эти ограничения, если только они не установят драйвер ядра на компьютер.
Некоторые приложения никому не будут выставлены, даже с соответствующими правами. Например, если я пишу банковское приложение, я не хочу, чтобы вы шпионили за тем, что будет отображать мое приложение:-). Другие приложения, такие как Outlook с DRM, не будут предоставлять ничего по тем же причинам.
Только поддержка текстового шаблона автоматизации пользовательского интерфейса может дать больше информации (например, слова), чем всего текста. Увы, этот конкретный шаблон не поддерживается ни IE, ни FF, даже если они поддерживают глобальную автоматизацию пользовательского интерфейса.
Так что, если все это не работает для вас, вам придется погрузиться глубже и использовать методы распознавания или распознавания фигур. Даже при этом в некоторых случаях вы вообще не сможете это сделать (из-за обеспечительных прав).
Это нетривиально, если приложение, за которым вы "следите", рисует текст самостоятельно. Одним из возможных решений является запуск другого приложения для рисования части его окна путем аннулирования области непосредственно под курсором.
Когда другое приложение будет рисовать, вам придется перехватывать вызовы рисования текста. Один из способов сделать это - вставить код в другое приложение и перехватить вызовы в функциях GDI, которые рисуют текст. Когда вы отлаживаете нативные приложения, это то, что Visual Studio делает для реализации точек останова. Чтобы проверить идею, вы можете использовать такую библиотеку, как обходные пути (но она не бесплатна для коммерческого использования).
Вы также можете проверить, поддерживает ли приложение один из API-интерфейсов доступа, которые есть в Windows, чтобы упростить такие вещи, как программы чтения с экрана для слепых людей.
Одно слово предостережения: я сам этого не делал.
Если приложение должно обрабатывать не только приложения.Net, я бы начал с импорта функций ( P / Invoke):
Позже вы можете перебирать элементы управления и пытаться получить текст изнутри, основываясь на типе. Если я найду время, я постараюсь опубликовать такой код.
После некоторой проверки, похоже, что лучший способ (к сожалению, сложный тоже) - подключиться к тексту GDI, что приведет к некоторому
Я бы повторил то, что сказал Патриккер, но я думаю, что нет надежного способа сделать то, что вы хотите.
Вы, вероятно, получили текст окна или что-то в этом роде. Но что, если курсор находится над окном, которое не использует текст окна для хранения своего содержимого? Windows не обязаны хранить свои данные определенным образом.
Это в конечном итоге указывает вам на распознавание символов, где вы смотрите на пиксели под курсором и пытаетесь выяснить, какие слова там. Но это не только очень нетривиально, но и небезопасно. Что если часть слова не видна, потому что она выходит за пределы окна?
Это определенно не тривиально. Есть несколько способов приблизиться к этому. Но нет надежного способа, который будет работать со всеми окнами.
Существует SDK для получения текста с помощью OCR. Это не бесплатно, но это довольно дешево по сравнению с другими продуктами: http://www.screenocr.com/screen-ocr-library-sdk.htm У них есть приложение, которое предоставляет те же функции, так что вы также можете попробовать демо.
Для достижения этого вам нужен многоплановый подход.
МСА работает во многих приложениях, но вам нужно поэкспериментировать, чтобы увидеть, где возвращается текст. Это может быть элемент, значение или диапазон. Нет согласованности даже между офисными приложениями.
Если происходит сбой UIA, перечислите таблицу запущенных объектов (ROT) и получите указатели COM на различные приложения, зарегистрированные в ROT. Затем вы можете привести эти указатели к базовым типам офисов:
например:
enumerate ROT - then
wb = (Excel._Workbook)enumerator.Value;
string strText = wb.Application.ActiveCell.Text.ToString();
Если вышеуказанные два метода не сработали, воспользуйтесь бесплатной системой распознавания текста в MODI (библиотека типов Microsoft Office Document Imaging 12.0)