当前推荐版本:StellarX v3.0.0

发布日期:2026 – 01 – 09

下载方式:

✨ 新增

日志系统使用Demo
路径:examples\SXLog-日志系统使用demo
轻量日志系统 SxLog(SxLogger / SxLogLine / SxLogScope / Sink / TagFilter / LanguageSwitch):
新增统一日志入口与宏封装,支持按级别与 Tag 筛选输出,支持控制台/文件落地与可选滚动(按大小阈值),并提供中英文双语文本选择能力(SX_T / SxT)。日志宏具备短路机制:未命中级别或 Tag 时不构造日志对象、不拼接字符串;输出侧以行级互斥保证多线程下不交错。该模块不依赖 WinAPI 调试输出通道、不引入第三方库。
典型用法:SX_LOGD/SX_LOGI/SX_LOGW/SX_LOGE/SX_LOGF/SX_LOG_TRACE + 流式拼接;SX_TRACE_SCOPE 作用域耗时统计
核心配置:setMinLevel(...)setTagFilter(...)enableConsole(true/false)enableFile(path, append, rotateBytes)setLanguage(ZhCN/EnUS)setGBK()



⚙️ 变更

TabControl 页签切换时序调整:
修改页签按钮切换逻辑为“先关闭当前已打开页,再打开目标页”,避免“先打开再关闭”在复杂容器/快照链路下引入的时序不确定性;对外 API 不变(涉及 TabControl::add 内部切换逻辑)
控件 Setter 语义收敛:
明确控件 Setter 的职责为“更新状态并标脏”,绘制统一由窗口/容器的重绘收口机制触发,降低生命周期耦合与快照污染风险(见下方相关修复条目)



✅ 修复

TextBox::setText 在进入事件循环前调用触发中断:
修复在窗口尚未初始化(未 initgraph()、图形上下文未就绪)前调用 TextBox::setText() 导致访问冲突崩溃的问题。旧实现将“状态更新”和“立即绘制”耦合,setText() 内部直接触发 draw(),进而在无图形上下文时进入 saveBackground()/getimage() 路径崩溃;现已移除 Setter 内直接绘制,仅保留赋值与置脏,绘制交由统一重绘流程完成。
TabControl 切换/关闭后 Table 新旧内容重叠(重影):
修复页签切换与表格重置数据后出现的稳定残影问题。根因是“快照未就绪阶段发生局部重绘”导致快照污染;本次回退 setIsVisible(true) 的“立即向上 requestRepaint”行为,改为仅置脏,并为 Canvas::requestRepaintTabControl::requestRepaint 增加护栏:当容器 dirtyhasSnap=0 或快照缓存无效时,禁止 partial fast-path,自动降级为全量重绘以保证快照链路正确性;同时修正 Table::setData(...) 列补齐边界问题,降低异常噪声

⚠️ 可能不兼容

删除 Button 尺寸别名 API(Breaking):
移除 Button::getButtonWidth() / Button::getButtonHeight(),统一使用基类 Control::getWidth() / Control::getHeight() 获取控件尺寸。该改动会导致旧代码在升级到 v3.0.0 后编译失败,但行为语义保持一致(仍读取同一 width/height)。
可见性/文本设置的“即时刷新”副作用移除:
setIsVisible(true)setText() 等 Setter 不再保证立刻触发绘制;如业务代码此前依赖“调用后立即可见”,需要确保后续存在一次重绘收口(窗口主循环/容器重绘/显式刷新)以完成视觉更新。 修复

📌 升级指引

Button 宽高接口迁移:
getButtonWidth()getWidth()
getButtonHeight()getHeight()
Setter 不再“立即绘制”的适配:
初始化阶段可先设置属性(如 TextBox::setText("default")),由首次 Window::draw() / 主事件循环的统一绘制完成可视刷新;
若在非事件驱动场景下程序化更新后需要立刻刷新,请确保触发一次统一重绘路径(避免在 Setter 内手动调用 draw() 造成生命周期耦合)。
SxLog 接入建议:
在程序入口完成基础配置(控制台输出/最低级别/语言),并使用统一 Tag(如 Dirty/Resize/Table/Canvas/TabControl)建立可回放的事件链路;高频路径建议通过级别与 Tag 控制噪声与 I/O 成本。


如何选择下载方式?

  • 方式 A:Release 包集成(推荐)
    直接在 GitHub Releases 下载对应版本压缩包,解压后按照「快速开始」文档,把 include/lib/ 挂到自己的 VS 工程中使用。
  • 方式 B:克隆源码自行编译
    适合需要阅读/修改源码、参与贡献的同学。使用 git clone 获取仓库后,可按 README 中的说明自行构建库文件。

详细的集成步骤见本站「快速开始」页面。


[v2.3.2] – 2025 – 12 – 20

✨ 新增

  • Table 支持运行期重置表头与数据:新增 Table::clearHeaders()Table::clearData()Table::resetTable(),允许同一 Table 在运行过程中动态切换表头与数据,并触发必要的单元格尺寸/分页信息重算与重绘。
  • TextBox 新增密码模式:TextBoxmode 新增 PASSWORD_MODE;输入内容内部保存,绘制层面使用掩码字符(如 *)替代显示,真实文本可通过 TextBox::getText() 获取。

⚙️ 变更

  • TabControl 默认激活页语义明确化:
    • 首次绘制前调用 TabControl::setActiveIndex():仅记录默认激活索引,不再立即触发页签按钮点击回调;
    • 首次绘制完成后:若设置了默认激活索引则应用激活状态并绘制激活页(索引越界时默认激活最后一个页);
    • 程序运行过程中调用 TabControl::setActiveIndex():索引合法则立即切换激活页并绘制;索引越界则不做处理。

✅ 修复

TabControl 由不可见设置为可见时绘制错乱:修复 setIsVisible(false) -> setIsVisible(true) 后非激活页被错误绘制导致的多页重叠/残影;现在 TabControl 可见时仅激活页可见/可绘制,无激活页则不绘制任何页。

TabControl::setActiveIndex 绘制前调用导致程序中断:修复绘制前设置默认激活索引时触发空指针访问的问题;现在默认激活逻辑延后到首次绘制完成后再生效,避免崩溃并保证首次绘制即可绘制激活页。

[v2.3.1] – 2025 – 11 – 30

🙏 鸣谢

  • 感谢用户 @To-KongBai 提供稳定复现步骤与关键现象对比(容器嵌套孙控件坐标转换问题),帮助我们快速确认多容器嵌套时的控件坐标转换问题并修复。(Issues#6
  • 在即将上线的官网中(ICP备案中)我们计划加入一个贡献者鸣谢墙,欢迎各位用户反馈BUG或者分享自己用星垣做的界面,我们将认真阅读并收录鸣谢
  • 真诚的感谢每一位反馈BUG的用户,你们的反馈将使星垣更加稳定和健壮

✨ 新增

新增一个登录界面Demo在主仓库examples/目录下

⚙️ 变更

  • Dialog背景快照机制:Dialog不在自己抓取和销毁快照,删除重载的抓取和恢复快照的方法,完全交由基类Canvas处理,Dialogdraw方法中不在处理快照
  • 窗口变化重绘时控件和窗口重绘的时机调整:主事件循环中窗口大小发生变化时先处理控件尺寸,并回贴和释放旧快照,然后再重绘新尺寸窗口,最后绘制控件

✅ 修复

Table动态改变坐标页码标签和翻页按钮错乱:Table控件的setX/Y中重置isNeedButtonAndPageNum状态为真,在绘制时重新计算翻页按钮和页码标签的位置以保持在表格正下方居中位置显示

容器嵌套时子控件坐标转化:Canvas重写了基类的setX/Y方法,在容器全局坐标发生变化时同步修改子控件的全局坐标,防止在容器嵌套时,容器的相对坐标被子控件当成全局坐标处理

纯色背景窗口标题不生效:Windowdraw()方法中强制设置窗口标题,以防止,创建窗口时传递的窗口标题不生效

选项卡控件页签打开时动态改变坐标背景残留:TabControl重写的setX/Y方法中,当选项卡的坐标发生变化时强制让所有页签以及页和子控件丢一次快照,防止,在修改坐标后因,快照恢复顺序引起的选项卡激活页残留

[v2.3.0] – 2025 – 11-18

✨ 新增

  • 新增LayoutMode自适应布局模式和Anchor锚点,控件中可以调用 setLayoutMode
    设置布局模式以及steAnchor设置锚点,达到窗口拉伸时控件自适应窗口变化。对话框控件在窗口变化时只会重新计算位置,来保证居中显示
  • Window新增adaptiveLayout()这个API由主事件循环调用,在窗口拉伸时根据锚点重新计算控件位置和尺寸,使左右/上下双锚定控件随窗口变化自动伸缩。

⚙️ 变更

  • 优化窗口尺寸调整机制:重构 WndProcThunkrunEventLooppumpResizeIfNeeded,统一记录窗口尺寸变化并在事件循环尾部一次性重绘,避免拉伸过程中重复绘制引发抖动与顺序错乱。
  • 新增对话框尺寸调度接口:引入 Window::scheduleResizeFromModal(),配合 pumpResizeIfNeeded() 使用。模态对话框显示期间,父窗口可实时更新客户区尺寸并在统一收口时重新布局子控件,对话框自身尺寸保持不变。
  • 重绘顺序优化:在窗口尺寸变化后的收口阶段使用 ValidateRect 代替 InvalidateRect,避免系统再次发送 WM_PAINT 导致重入绘制。
  • 其他改进:修复表格翻页按钮与页码标签等元素背景快照更新不及时的问题;改进对话框背景捕捉逻辑。

✅ 修复

稳定性修复:修正某些情况下窗口尺寸突变导致的异常帧;解决表格和对话框背景快照在边界条件下未及时更新的问题。

模态对话框拉伸修复:解决了模态对话框弹出时,窗口拉伸无法让底层控件按照锚点更新尺寸和位置的问题;同时避免对话框反复重绘导致残影。

绘制顺序错乱修复:解决窗口拉伸时偶发的绘制顺序紊乱、控件残影和边框闪烁问题,确保控件按添加顺序依次绘制。

[v2.2.2] – 2025 – 11- 08

⚙️ 变更

  • Canvas容器坐标传递方式改变,子控件坐标由原来的传递全局坐标改为传递相对坐标(坐标原点为容器的左上角坐标可通过getX/Y接口获得)可以设置子控件坐标为负值
  • examples\register-viewer下的案例已同步修改为最新,同步容器子控件为相对坐标

✅ 修复

表格控件在窗口变化时其翻页按钮和页码标签背景快照更新不及时的问题

修复窗口拉伸(左/上边)时的抖动/弹回与闪烁

WM_SIZING 仅做最小尺寸夹紧;WM_GETMINMAXINFO 设置窗口级最小轨迹

拖拽期冻结重绘,松手统一收口;WM_SIZE 只记录尺寸不抢绘制

禁用 WM_ERASEBKGND 擦背景并移除 CS_HREDRAW/CS_VREDRAW,减少闪烁

对话框的相关问题

对话框关闭后概率出现功能按钮残留

模态对话框触发时,窗口拉伸无法重绘或背景错乱

[v2.2.1] – 2025 – 11 – 4

此版本为v2.2.0的修复版本

✅ 修复

  • TabControl类重写了基类的setDirty方法保证页签+页列表同步更新状态
  • Canvas容器和特殊容器TabControl以及对话框Dialog重写requestRepaint方法,控件向上冒泡时传递父指针,请求重绘时只向上到父一级,不再传递到根。并且不再重绘整个父容器,而是由父容器重绘标脏的子控件,避免了频繁真个容器重绘导致的频闪
  • Dialog中重写了saveBackgroundrestBackground方法,保证对话框关闭后不会有边框残留

⚙️ 变更

彻底禁用Control的移动构造Control(const Control&) = delete; Control& operator=(const Control&) = delete; Control(Control&&) = delete; Control& operator=(Control&&) = delete;


更多历史版本请移步主仓库更新日志


版本号与兼容性说明

StellarX 采用 主版本.次版本.修订号 的版本号规则:

  • 主版本号:框架架构或 API 有较大调整时升级,例如 v1.x → v2.x。
  • 次版本号:添加新功能、重要优化但保持基本兼容。
  • 修订号:Bug 修复与小改动。

一般情况下,次版本号升级(例如 2.1 → 2.2)保持项目代码基本可用,但可能有少量 API 命名调整,详细见对应 Release 说明。
建议在升级前简单查看更新日志,并保留一份旧版本备份。


路线图(简要)

  • ✅ 常用控件与事件体系
  • ✅ 文档站与示例 Demo
  • ⏳ StellarX Pro(进阶版,面向中小型桌面应用)
  • ⏳ 更多模板工程 / 项目脚手架
  • ⏳ 自动化测试与 CI

详细计划与讨论请见 GitHub 仓库的 Issues / Discussions或本站首页未来规划。