windowcapture
исходный код / INPUT_FIELD_ACCESS.md

INPUT_FIELD_ACCESS.md

29 строк · 5,462 байт · модуль Docs
 1# Чтение/замена поля ввода в реальном времени — методы
 2
 3> Какие есть «имбовые» методы читать поле ввода в ЛЮБОМ приложении и менять текст на месте, **не трогая буфер обмена и не переключая фокус/поле/приложение**. Сравнение + что используем.
 4
 5## Сравнение методов
 6| Метод | Чтение | Замена «на месте» | Кросс-приложение | Трогает буфер/фокус? | Сложность |
 7|---|---|---|---|---|---|
 8| **TSF (Text Services Framework)** | да (ITfContext/ITfRange) | **да — в любом TSF-приложении** (так работают IME/системная автозамена/спелл) | широко (совр. приложения) | нет | **очень высокая** (отдельный COM TIP + регистрация языкового профиля) |
 9| **UIA TextPattern** | **да** (строка/слово/предложение/каретка, любой уровень) | **нет** (read-only по спецификации) | широко (Chrome/WPF/UWP/Win32) | нет | средняя — **уже есть в `CursorReader`** |
10| **UIA ValuePattern** | всё значение | только **всё значение целиком** (SetValue) — простые однострочные поля | средне | нет | низкая |
11| **Win32 `EM_SETSEL`+`EM_REPLACESEL`** | да | да — для стандартных EDIT/RICHEDIT | только Win32-контролы (не Chromium/Electron/UWP) | нет | низкая, но строка cross-process ненадёжна |
12| **Инъекция клавиш (backspace+ввод в каретке)** | — | **да — в текущем фокусном контроле** | **универсально** | **НЕТ** (буфер/фокус не трогаются) | низкая |
13| Буфер (Ctrl+A / Ctrl+C / Ctrl+V) | да | да | универсально | **ДА — трогает буфер и выделение** ← это и вызывало «переключение» | низкая |
14
15## Вывод (подтверждено: так делает и Grammarly)
16- **Читать поле** = **UIA TextPattern**. Неинвазивно (без буфера и смены фокуса), даёт строку/слово/каретку на любом уровне. У нас **`CursorReader` уже на нём** (+ fallback WM_GETTEXT/EM_GETSEL для Win32). Это и есть «имбовый метод просмотра поля».
17- **Менять на месте** = **инъекция backspace+ввод в позиции каретки** (`QueueReplaceRaw`). Неинвазивна: **ни буфера, ни смены фокуса/поля/приложения**. Именно **буферный путь** (Ctrl+A/C/V в `CorrectEntireText`) переключал контекст — для real-time его не используем.
18- **Золотой стандарт на будущее** = **TSF** (правка in-place в любом приложении как системная автозамена), но это крупный отдельный COM-компонент — отдельный большой трек.
19
20## Реализовано (real-time авто-замена)
21Флаг `Settings.SentenceAiAutoApply` (по умолчанию **ВЫКЛ**; тумблер в трее автозамены «SAGE авто-замена предложения (эксп.)»):
22- В авто-режиме по-словная эвристика-правка **отключается** → текст на экране = набранному (точный счёт символов для замены).
23- На конце предложения (`. ? !` / Enter) текст предложения прогоняется через **тёплый SAGE** (орфография + **окончания** + **пунктуация** + регистр, двусторонний контекст).
24- Применяется **на месте** (`QueueReplaceRaw`: backspace+ввод в каретке) **только если пользователь не печатал во время вызова** (race-guard `typeSeq`) — иначе пропуск (никогда не портим текст).
25
26⚠️ **Ограничения (честно):**
27- Срабатывает на **конце предложения**, а не на каждом слове — посимвольный SAGE (0.3с) слишком медленный для каждой клавиши. «Каждое слово мгновенно с окончаниями/контекстом» = **TSF** или своя **tiny-NN** (этап 2, обучить на вашей 4080).
28- Замена backspace-ом надёжна, пока курсор в конце предложения; guard это страхует, но в редких гонках просто пропустит правку (безопасно).
29- **Не протестировано вживую** (computer-use отключён) → флаг по умолчанию выключен; проверять руками: `--textassist` → трей → включить «SAGE авто-замена предложения (эксп.)».