Лучший способ получить слово перед курсором в текстовом поле любого открытого приложения - PullRequest
1 голос
/ 15 января 2010

Я пишу приложение для ввода текста, которое находится в системном трее и помогает вводить текст с помощью клавиатурных хуков. Текущий символ, который вводит пользователь, определяется предыдущими буквами.

Так что, если у вас есть «Я хочу бен |» где "|" представляет каретку, когда пользователь нажимает на клавиатуру, следующая буква определяется путем вычисления предыдущих букв слова «бен». Это может оказаться 'd'> "bend" или "t"> "beent" и т. Д.

Это прекрасно работает, если я начинаю каждое слово с нуля, я могу просто отслеживать слово в строке в моей программе.

Проблема возникает, когда я кладу курсор на середину слова. Мне нужно определить, какие персонажи стоят перед позицией каретки. Ситуация также возникает, если я нажимаю клавиши со стрелками и т. Д.

В прошлом приложении AutoHotkey я делал это, отправляя команду «Shift + Ctrl + Стрелка влево» для выделения символов, команду «Ctrl + C» для ее копирования, а затем сохранял буфер обмена в моей строке. Я надеюсь, что в более надежном языке, таком как C #, я смогу избежать неприятного выделения артефактов этой техники. Есть ли способ получить персонажей программно?

Обратите внимание, что это должно происходить в любом текстовом поле в приложениях, поэтому я не могу получить символы из самого текстового поля (если нет способа доступа к текущему текстовому полю, находящемуся в фокусе).

Что вы думаете?

Ответы [ 3 ]

3 голосов
/ 15 января 2010

Таким образом, с традиционным .NET TextBox вы можете определить позицию каретки, используя свойство SelectionStart.Так что я бы сделал, чтобы определить, когда текст меняется, и посмотреть, где находится курсор.Вот небольшой пример кода, который вы можете адаптировать к вашей ситуации:

// first find the caret position
int caretPosition = MyTextBox.SelectionStart;

// now find all text that occurs before the caret
string textUpToCaret = MyTextBox.Text.Substring(0, caretPosition);

// now we can look for the last space character in the
// textUpToCaret to find the word
int lastSpaceIndex = textUpToCaret.LastIndexOf(" ");

if (lastSpaceIndex < 0)
    lastSpaceIndex = 0;

string lettersBeforeCaret = textUpToCaret.Substring(lastSpaceIndex);
3 голосов
/ 16 января 2010

Не существует надежного способа получить «текущее текстовое поле». Любое приложение может развернуться самостоятельно, поэтому вы не знаете, что искать. И если приложение не будет взаимодействовать с такими вещами, вы не сможете его форсировать. Ну, я думаю, вы всегда можете попытаться сделать снимок экрана и сделать OCR на нем, но это не очень реалистично.

Однако приложение, написанное с использованием набора инструментов виджетов приличного качества (или с использованием фондовых элементов управления), должно поддерживать Microsoft Active Accessibility , который обеспечивает стандартизированный способ доступа к пользовательскому интерфейсу этого приложения - или, скорее, некоторое абстрактное представление о том пользовательском интерфейсе, который оптимизирован для извлечения информации из него такими инструментами, как программы чтения с экрана. Похоже на то, что вы хотели бы, за исключением того, что я не знаю способа извлечь информацию о тексте , предшествующем выделению (каретка - это просто выделение шириной 0) из элемента управления с использованием MSAA.

0 голосов
/ 15 января 2010

Скорее всего, вам придется программно определить идентификаторы текстовых полей, которые редактируются, а затем отправить сообщение Windows (с помощью вызовов PostMessage или SendMessage), чтобы получить текст текстового поля. Я забыл, какая константа сообщения была необходима для извлечения текста, но есть способ использовать Windows API.

Перечень C # сообщений, которые вы можете попытаться отправить в приложения Windows, можно найти здесь .

Кроме того, я бы предложил отладку с помощью такой программы, как Spy ++ или Winspector spy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...