3.6 KiB
3.6 KiB
Fix-BUG-20260109-0001
适用场景:记录某个 BUG 的修复方案、影响评估、验证结果与落地信息。
关联信息
- Fix ID: Fix-BUG-20260109-0001
- 关联 BUG ID: BUG-20260109-0001
- 修复目标: 修复 TextBox 在 Window 创建 / 绘制前调用
setText()设置默认文本时因即时绘制导致的崩溃。 - 状态:已完成
- 负责人: 未记录
- 分支 / 版本: master / v3.0.0
根因分析
- 根因:
TextBox::setText()将“状态更新”和“立即绘制”耦合在一起。窗口尚未initgraph()、EasyX 图形上下文未就绪时,draw()内部进入Control::saveBackground(),调用SetWorkingImage()/getimage()等依赖有效图形环境的逻辑,最终崩溃。 - 触发条件: 创建 TextBox 后,在 Window 初始化 / 首次绘制前调用
TextBox::setText()。 - 为什么之前没发现:[可选] 常规示例多为 Window 完成初始化后再设置文本,缺少控件生命周期前置调用的最小回归用例。
- 关键证据:[可选] 调用链为
TextBox::setText()->TextBox::draw()->Control::saveBackground()-> EasyX 图形上下文相关 API。
修复方案
- 修复思路:
TextBox::setText()改为仅执行文本赋值和脏标记更新,不再在 setter 内直接调用draw();绘制统一交给 Window / 容器重绘流程。 - 关键改动:
- 移除
TextBox::setText(std::string text)中的直接draw()调用。 - 保留长度裁剪、文本赋值、
dirty=true。 - 将可视更新延后到后续统一重绘周期。
- 移除
- 涉及文件 / 类 / 函数:
TextBox.cppTextBox::setText()
- 影响的 API / 行为:[可选] 对外 API 不变;
setText()不再保证即时绘制。 - 关键约束 / 不变量:[可选]
- setter 不得直接调用
draw()或任何依赖图形上下文的 API。 saveBackground()/getimage()/putimage()/SetWorkingImage()只能在 Window 图形上下文就绪并进入统一绘制流程后执行。
- setter 不得直接调用
- 回滚点 / 开关:[可选] 回退 setter 内即时绘制逻辑。
影响评估
- 影响范围: TextBox 默认文本设置、程序化文本更新、绘制时序。
- 兼容性影响:有(如果外部代码依赖
setText()的即时绘制副作用,需要调整为触发一次重绘或等待绘制周期) - 行为变化:有(
setText()语义收敛为更新状态并标脏) - 性能影响:正向或无影响,减少 setter 内重复绘制与抓屏开销。
- 回归风险:
- 程序化调用
setText()后,如果应用没有触发任何重绘路径,界面更新可能延迟。 - 依赖即时刷新语义的旧代码可能出现短暂视觉滞后。
- 程序化调用
验证结果
- 验证步骤:
- 构造最小复现:在 Window 创建 /
draw()前创建 TextBox 并调用setText("default"),确认不再崩溃。 - Window 初始化后,通过事件输入或直接调用
setText()更新文本,确认后续一次重绘时文本正确显示。 - 覆盖 INPUT / READONLY / PASSWORD 三种模式,确认长度裁剪与显示逻辑不受影响。
- 覆盖窗口 resize,确认背景快照机制仍按既有逻辑工作,无残影或错位。
- 验证结果: PDF 历史记录标记已修复。
- 回归检查:[可选] TextBox 三模式输入与显示、背景快照保存 / 恢复 / 丢弃、Window 首次绘制、对话框打开 / 关闭强制重绘、resize 收口重绘。
- 验证证据:[可选]
落地信息
- Commit:
5cb59b3652 - PR:[可选] git
- 发布版本: v3.0.0
- 备注: 来源原始 Fix 记录未包含
-XXXX后缀,入库时按 BUG ID 补充为Fix-BUG-20260109-0001。