Files
StellarX-kaifa/开发记录/Fix/Fix-BUG-20260109-0001-TextBox-setText进入事件循环前调用崩溃.md
T

3.6 KiB
Raw Blame History

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.cpp
    • TextBox::setText()
  • 影响的 API / 行为:[可选] 对外 API 不变;setText() 不再保证即时绘制。
  • 关键约束 / 不变量:[可选]
    • setter 不得直接调用 draw() 或任何依赖图形上下文的 API。
    • saveBackground() / getimage() / putimage() / SetWorkingImage() 只能在 Window 图形上下文就绪并进入统一绘制流程后执行。
  • 回滚点 / 开关:[可选] 回退 setter 内即时绘制逻辑。

影响评估

  • 影响范围: TextBox 默认文本设置、程序化文本更新、绘制时序。
  • 兼容性影响:有(如果外部代码依赖 setText() 的即时绘制副作用,需要调整为触发一次重绘或等待绘制周期)
  • 行为变化:有(setText() 语义收敛为更新状态并标脏)
  • 性能影响:正向或无影响,减少 setter 内重复绘制与抓屏开销。
  • 回归风险:
    • 程序化调用 setText() 后,如果应用没有触发任何重绘路径,界面更新可能延迟。
    • 依赖即时刷新语义的旧代码可能出现短暂视觉滞后。

验证结果

  • 验证步骤:
  1. 构造最小复现:在 Window 创建 / draw() 前创建 TextBox 并调用 setText("default"),确认不再崩溃。
  2. Window 初始化后,通过事件输入或直接调用 setText() 更新文本,确认后续一次重绘时文本正确显示。
  3. 覆盖 INPUT / READONLY / PASSWORD 三种模式,确认长度裁剪与显示逻辑不受影响。
  4. 覆盖窗口 resize,确认背景快照机制仍按既有逻辑工作,无残影或错位。
  • 验证结果: PDF 历史记录标记已修复。
  • 回归检查:[可选] TextBox 三模式输入与显示、背景快照保存 / 恢复 / 丢弃、Window 首次绘制、对话框打开 / 关闭强制重绘、resize 收口重绘。
  • 验证证据:[可选]

落地信息

  • Commit: 5cb59b3652
  • PR:[可选] git
  • 发布版本: v3.0.0
  • 备注: 来源原始 Fix 记录未包含 -XXXX 后缀,入库时按 BUG ID 补充为 Fix-BUG-20260109-0001。