1# WindowCapture — План разделения на модули 2 3> Составлено 2026-06-03. Цель (из ТЗ автора): «отдельно скриншотер, отдельно всё остальное». Граф связанности подтверждён грепом точек инстанцирования и перекрёстных ссылок — связанность рыхлая, разделение реалистично без переписывания логики. 4 5## 1. Фактический граф связанности (кто кого создаёт) 6``` 7Program.cs ──► TrayApp | EditorForm(file) | AudioPlayerForm(file) (роутинг по аргументу) 8TrayApp ──► Controller, SearchForm, SoundpadForm, SettingsDialog 9Controller ──► FrozenOverlay ──► Detector ──► EditorForm(bitmap) ← ЯДРО: захват→редактор 10 ├─► TextProcessor (глоб. хук → орфография/T9) ← отдельный концерн 11 ├─► VideoRecorder + RecordingOverlay ← запись 12 ├─► ClipboardForm ← буфер 13 └─► MediaParser ──► MediaDownloadDialog ← загрузка 14EditorForm ──► AnnotationCanvas, WordSidePanel ──► WordIntegration/GeminiIntegration, SettingsDialog 15SearchForm ──► EditorForm(file).Show() ← ЕДИНСТВЕННАЯ «лишняя» связь, легко разорвать 16``` 17**Вывод:** `Word/Gemini/AnnotationCanvas` замкнуты на редактор; `TextProcessor`, `AudioPlayerForm`, `SoundpadForm`, `SearchForm`, рекордер, буфер — почти не связаны с ядром (общаются только через `Settings` и `Native/WinApi`). 18 19## 2. Целевая структура 20| Сборка (output) | Тип | Что входит | Зависит от | 21|---|---|---|---| 22| **WC.Core.dll** | class library | `Native/*`, `Effects/*`, `Helpers/{Bitmap,Color,Font,Blur,Glow,Logger,MediaTypes}`, `UI/Controls/*`, `Models/{Settings,KeyBindings}`, `D2DRenderer` | — | 23| **WC.Screenshot.exe** (флагман) | winexe | `App/*`, `Detection/Detector`, `FrozenOverlay`, `EditorForm.*`, `AnnotationCanvas`, аннотации, `Integration/*` (Word+Gemini), `WordSidePanel`, экспорт-диалоги, `SettingsDialog` | Core | 24| **WC.TextAssist.exe** | winexe (трей) | весь spell-стек (`TextProcessor`, `SymSpell`, `CompactSpell`, `CharNN`, `CharEmbedNet`, `BigramLM`, `RulesEngine`, `MorphAnalyzer`, `BloomFilter`, `CursorReader`) + свой клав-хук + `Data/` (~95 МБ моделей) | Core | 25| **WC.AudioPlayer.exe** | winexe | `AudioPlayerForm`, MF/WASAPI interop, метаданные | Core | 26| **WC.Recorder** (или плагин) | модуль | `Recording/*`, `RecordingOverlay`, `VideoRecorder` | Core | 27| **WC.Soundpad.exe** | winexe (admin) | `SoundpadForm`, `APO/*` (нативный драйвер) | Core | 28| **WC.Tools** (вспомогат.) | модуль/плагин | `ClipboardForm`, `SearchForm`, `MediaParser`, `MediaDownloadDialog`, видеоплеер | Core | 29 30**Приоритет извлечения (по ценности и чистоте границы):** 311. **WC.TextAssist** — самый чужеродный концерн (системный автокорректор), тянет ~95 МБ моделей и свой хук. Вынос сразу облегчает «скриншотер» по весу, рискам антивируса (глоб. хук + инъекция WM_CHAR) и поверхности багов. 322. **WC.Soundpad** — нативный APO-драйвер + админ-права + правка реестра. Совершенно отдельный класс рисков; держать его в скриншотере вредно для доверия/антивируса. 333. **WC.AudioPlayer** — уже фактически отдельное приложение (запуск по файлу), нулевая связь с редактором. 344. Дальше по желанию: рекордер, буфер/поиск/загрузчик — в плагины. 35 36## 3. Связи, которые надо разорвать (их мало) 37- **`SearchForm → new EditorForm()`** (`SearchForm.cs:463`): заменить на запуск процесса скриншотера: `Process.Start("WC.Screenshot.exe", path)`. Так Search перестаёт зависеть от ядра редактора. 38- **`Controller → TextProcessor`** (`Controller.cs`, обработчики хука): при выносе TextAssist — перенести в его собственный клав-хук. В скриншотере вызовы TextProcessor убрать. 39- **`Controller → VideoRecorder/ClipboardForm/MediaDownloadDialog`**: если выносить — заменить на запуск соответствующего exe/плагина или оставить в скриншотере как опц. модуль. 40- Всё остальное общается через `Settings`/`Native` → уедет в `WC.Core` и связь сохранится автоматически. 41 42## 4. Сборка (текущая — csc.exe + PowerShell, без .sln) 43Сейчас `build.ps1` собирает один winexe из всех `.cs`. Перейти на несколько выходов: 441. **WC.Core.dll**: `csc /target:library /out:WC.Core.dll <core .cs>` + ссылки на System/Drawing/Forms/WPF(UIAutomation). 452. Каждый exe: `csc /target:winexe /out:WC.X.exe /r:WC.Core.dll <module .cs>`. 463. Один общий `Settings.ini`/конфиг в `%APPDATA%/WindowCapture` (уже так) → модули делят настройки. 474. (Рекомендация на будущее) Завести `.sln` + `.csproj` per модуль — заработает IntelliSense/MSBuild/CI на GitHub Actions; csc-скрипты оставить как fallback. 48 49## 5. Поэтапная миграция (каждый шаг компилируется) 50- **Шаг 0** — namespace уже единый (`WindowCapture.*`); ничего не ломать. Зафиксировать baseline (есть в git). 51- **Шаг 1** — собрать `WC.Core.dll` из «фундамента» (§2) **не двигая файлы**: просто отдельная компиляция core-подмножества в dll, остальное — exe со ссылкой на неё. Проверить, что всё ещё собирается и работает (smoke-test). 52- **Шаг 2** — вынести **WC.TextAssist**: перенести spell-файлы + `Data/` в подпроект, дать ему свой `Main`+трей+хук, убрать вызовы `TextProcessor` из `Controller`. Скриншотер собирается без spell-стека. 53- **Шаг 3** — вынести **WC.Soundpad** и **WC.AudioPlayer** (почти нет связей). 54- **Шаг 4** — разорвать `SearchForm→EditorForm` (Process.Start), вынести Tools. 55- **Шаг 5** — рекордер/буфер/загрузчик по желанию. 56- На каждом шаге: `build` зелёный + smoke-test ключевого пути. 57 58## 6. Риски и что проверить 59- **Общий конфиг**: несколько процессов пишут `settings.ini` — возможны гонки записи. Решение: каждый модуль пишет свою секцию/файл, либо запись через `Mutex`. 60- **Иконка трея ×N**: если TextAssist и Soundpad — отдельные трей-приложения, у пользователя несколько иконок. Решение: единый «лаунчер»-трей или общий трей-хост. 61- **Глобальный хук только один на процесс**: TextAssist ставит свой LL-хук; убедиться, что скриншотер больше не ставит клав-хук (он ему нужен только для активации захвата — оставить, но не для T9). 62- **`Data/` 95 МБ** уезжает только в TextAssist → скриншотер резко легчает. 63- **Что НЕ трогать на этом этапе**: незавершённые/экспериментальные подсистемы (мёртвый D2D-путь SearchForm, отключённые нейромодели) — чистить до выноса, а не во время. 64 65## 7. Связь со стратегией (FEATURE_RESEARCH) 66- Лёгкий, сфокусированный **WC.Screenshot** с фишкой **AI→Word** = флагман и уникальная ниша. Разделение прямо снимает главную жалобу рынка на «комбайны» (ShareX). 67- **WC.TextAssist** — самостоятельный продукт (системный автокорректор RU/EN) со своей аудиторией. 68- Приватность local-first сохраняется во всех модулях.