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

MODULARIZATION_PLAN.md

68 строк · 9,421 байт · модуль Docs
 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 сохраняется во всех модулях.