# 新增功能模块 / 模块重构 > 适用场景:新增模块、重大模块重构、核心架构能力演进。 > 不适用场景:小接口或轻量功能变更,请使用“功能变更”模板。 ## 基本信息 - 模块 ID:Module-20260409-0001 - 模块名称:Window 托管重绘与覆盖合成机制 - 状态:已完成 / 待持续回归 - 类型:架构演进 - 所属系统 / 子系统:Window / Control / Dialog 重绘链 - 版本 / 分支:`master` - 环境:Windows + EasyX + VS2022 - 负责人:Codex 协作修改 ## 背景与目标 - 背景: - 初始框架以控件局部即时重绘为主,非模态对话框与底层控件重叠时,容易出现底层先画、对话框后补的层级问题。 - 当前痛点: - 对话框遮挡下的 hover / click / tooltip / 分页等交互容易闪烁 - 底层控件和上层对话框在事件里分离绘制,顺序不可控 - 目标: - 将“事件改状态”和“绘制提交”拆开,由 `Window` 在事件尾统一提交重绘。 - 非目标:[可选] - 暂不做真正像素级脏区裁剪 - 暂不统一布局系统 ## 模块边界 - 职责: - 在 `Window` 主循环里托管控件重绘请求 - 选择安全的重绘 root - 在提交阶段维护普通控件与非模态 `Dialog` 的正确层级 - 不负责什么: - 模态 `Dialog` 自己的内部事件循环 - 布局语义统一 - 字符集问题 - 外部依赖: - EasyX 绘制接口 - 各控件自身的快照恢复能力 - 对外能力 / API: - `Window::requestManagedRepaint(Control* source)` - `Window::flushManagedRepaint()` - `Control::getManagedRepaintRoot()` - `Control::commitManagedRepaint()` - 关键数据 / 状态: - `managedDispatchActive` - `managedSceneDirty` - `managedRepaintItems` ## 设计说明 - 核心流程: 1. `Window::runEventLoop()` 开始输入分发前,进入 `managedDispatchActive = true` 2. 控件在 `handleEvent()` 中只改状态并通过 `requestRepaint()` 上报 3. `Window::requestManagedRepaint(source)` 把 source 转换成 `root + coverage` 4. 事件收口时 `flushManagedRepaint()` 按层级提交 root 5. 最后补画和脏区相交的非模态 `Dialog` - 关键对象 / 类关系: - `Window`:重绘调度中心 - `Control`:提供宿主窗口回溯与 root 选择语义 - `Canvas / TabControl / Dialog`:作为安全重绘 root 的主要容器 - 生命周期: - 托管重绘项只存在于当前分发轮次 - `clearManagedRepaintState()` 在 flush、resize 收口、对话框开关后的整场景重绘后清空 - 事件 / 渲染 / 数据流: - 事件:Dialog 优先,普通控件其次 - 渲染:受影响普通 root 先画,Dialog 后补 - 数据流:leaf control -> requestRepaint -> Window registry -> flush - 关键不变量: - 分发期不直接提交托管重绘 - 顶层普通控件的提交顺序必须服从 `Window::controls` 的 z-order - 对话框始终绘制在普通控件之上 - 降级 / 回退策略:[可选] - `resize`、对话框打开/关闭等全局变化仍走整场景重绘 ## 实现与影响 - 关键实现点: - `Control` 增加 `hostWindow`、`getManagedRepaintRoot()`、`commitManagedRepaint()` - `Window` 增加 `ManagedRepaintItem` 队列 - `Canvas / TabControl / Dialog` 提供局部可提交与升级为整 root 重画的判断 - 涉及文件 / 类 / 函数: - `Window.h / Window.cpp` - `Control.h / Control.cpp` - `Canvas.h / Canvas.cpp` - `TabControl.h / TabControl.cpp` - `Dialog.h / Dialog.cpp` - 兼容性影响: - 行为层面更严格,底层控件不再依赖旧的“即时局部重绘”副作用 - 性能影响: - 相比整场景重绘更细 - 相比纯即时局部重绘更稳定 - 在全局变化场景仍保留整场景兜底 - 风险点: - root 选择错误会导致局部重绘不完整 - 嵌套容器组合场景需持续回归 ## 测试与验证 - 测试范围: - 非模态遮挡下的按钮 hover / click - `Canvas / TabControl / Table` 组合场景 - 模态与非模态对话框 coexist 场景 - 验证步骤: 1. 编译 `Control / Canvas / TabControl / Dialog / Window` 相关源文件。 2. 回归 `KEY == 2 / 3 / 4` 的对话框与遮挡场景。 3. 检查对话框关闭、resize、hover 清理和局部重绘顺序。 - 验证结果: - 第二阶段架构已落地,核心编译通过,主问题链路已被压住。 - 已知限制 / 遗留问题:[可选] - 快速划过多个按钮时偶发一帧双高亮,当前接受为底层限制 - 仍未推进到真正像素级脏区裁剪 ## 落地信息 - 关联功能变更 ID:[可选] - `Feature-20260409-0002` - `Feature-20260409-0003` - 关联 BUG / Fix:[可选] - `BUG-20260409-0001` - `Fix-BUG-20260409-0001` - Commit: - `b07a4ec` - `77a8fe5` - 当前工作区未提交阶段 - PR:[可选] - 发布版本:[可选] - 相关文档:[可选] - `00-修改总览-20260409.md`