跳转至

SOUI3 到 SOUI5 迁移指南

本指南帮助开发者从 SOUI3 平滑迁移到 SOUI5,了解主要变化和升级步骤。

版本演进概述

SOUI 版本发展历史

  • SOUI3:最初的 SOUI 版本,奠定了框架基础
  • SOUI4:基于 SOUI3 重构,重点实现 COM 接口化,便于其他语言调用
  • SOUI5:在 SOUI4 基础上进一步优化,扩展跨平台支持

SOUI4 与 SOUI5 的主要差异

特性 SOUI4 SOUI5
平台支持 仅支持 Windows 支持 Windows、Linux、macOS
功能优化 基础功能完善 大量细节优化,功能更丰富稳定
图像解码 使用 png 解码器 删除 png 解码器,全面使用 stb 解码器
APNG 支持 依赖 png 解码器 stb 解码器原生支持

从 SOUI3 到 SOUI4 的重大变化

1. 接口调用约定调整

  • SOUI3:接口调用约定为 __cdecl
  • SOUI⅘:接口调用约定为 WINAPI(__stdcall)

2. 接口参数传递方式变化

  • SOUI3:接口返回值可能为各种对象
  • SOUI⅘:接口返回值全部调整为基本数据类型,原返回对象的方法改为使用 out 参数

3. 事件定义机制重构

SOUI3 事件定义方式

SEVENT_BEGIN_EX(EventTimer, EVT_TIMER, on_timer, SOUI_EXP)
    UINT uID;
SEVENT_END()

SOUI⅘ 事件定义方式

DEF_EVT(EventTimer, EVT_TIMER, on_timer, {
    UINT uID;     ///< 定时器ID
    LPARAM uData; ///< 定时器数据
})

主要变化说明: - SOUI⅘ 中定义事件时会自动生成对应的数据结构体(如 EventTimerSt) - 可通过 IEvtArgs::Data() 方法获取事件数据结构体指针 - 原 idFromnameFromsender 成员被移除 - 改为使用 IEvtArgs::IdFrom()IEvtArgs::NameFrom()IEvtArgs::Sender() 方法访问

4. 类型定义方式更新

SOUI3 类型定义

SOUI_CLASS_NAME(SCaption, L"caption")
第一个参数是新对象的类名,第二个参数是 XML 中的节点名。

SOUI⅘ 类型定义

DEF_SOBJECT(SWindow, L"caption")
第一个参数是新对象的基类名,第二个参数是 XML 中的节点名。

优势: - 可使用 __baseCls typedef 获取基类名,实现继承 - 兼容 GCC 编译器(GCC 不支持 __super

5. 宿主定义调整

  • SOUI3SHostWndSHostDialog 支持使用 SOUI_CLASS_NAME 声明
  • SOUI⅘:不再支持这种声明方式

6. 资源管理增强

SUiDef 模块

SOUI4 引入 SUiDef 模块管理 UI 资源: - 一个程序可包含多个 SUiDef 模块 - 每个模块可管理多个 UI 资源 - 更好地隔离不同模块使用的 UI 资源

私有资源定义

完善页面私有资源定义,防止资源冲突: - 页面加载完成后,私有资源自动隐藏 - 外层代码默认无法访问这些资源

兼容性处理:

// 关闭私有资源隔离功能(兼容 SOUI3 写法)
SHostWnd::SetHideLocalUiDef(FALSE);

// 动态创建元素时访问私有资源
SHostWnd::EnablePrivateUiDef(TRUE);  // 获取访问权限
// ... 使用资源 ...
SHostWnd::EnablePrivateUiDef(FALSE); // 关闭访问权限

注意: - SetHideLocalUiDef 是静态方法 - EnablePrivateUiDef 是成员方法,仅适用于当前页面

7. 字符串类型使用变化

SOUI3 中的 SStringA/SStringW

  • 未继承任何基类
  • 只有一个成员:LPSTR m_psz(或 LPWSTR m_psz
  • 可直接兼容 printf 的 %s 参数

SOUI⅘ 中的 SStringA/SStringW

  • 继承 IStringA/IStringW 接口
  • 无法直接兼容 printf 的 %s 参数
  • 需显式调用 SStringA::c_str() 方法
// SOUI3 可直接使用
printf("%s", str);

// SOUI4/5 需要显式调用 c_str()
printf("%s", str.c_str());

8. 构建系统变更

  • SOUI3:使用 QMake 构建系统,提供 bat 生成 VS 工程能力
  • SOUI⅘:全面切换到 CMake 构建系统,不再提供 bat 生成能力

9. xml类型变化

  • SOUI3:直接使用utilities中引用的pugixml来解析xml。
  • SOUI⅘:使用 SOUI 基于pugixml包装的SXml解析器。

10. ResProvider的创建

  • SOUI3:使用全局函数CreateResProvider来创建ResProvider。
  • SOUI⅘:使用SouiFactory来创建ResProvider。

11. GdiObject对象重命名

  • SOUI⅘:GdiObject的接口有变化,增加了S后缀,比如IPenS, IBrushS, IBitmapS, IRegionS, IPathS等,主要是为了避免和C++标准库的类名冲突。

12.其它

  • XxxView的适配器接口有调整,所有方法都统一使用WINAPI调用,原SWindow的参数替换为SItemPanel, 原pugi::xml_node替换为SXmlNode。
  • SHostWnd不直接继承自SWindow,而是只继承SNativeWnd, 需要使用GetRoot()来获取顶层SWindow*
  • SXmlDoc对象和pugi::xml_document一个区别在于SXmlDoc不继承SXmlNode, 要获取root节点,可以使用SXmlDoc.root()方法。
  • SEventArgs替换为IEvtArgs

迁移建议

逐步迁移策略

  1. 评估现有代码:分析项目中使用的 SOUI3 特性和自定义组件
  2. 环境准备:搭建 SOUI5 开发环境
  3. 依赖更新:替换 SOUI3 库为 SOUI5 库
  4. 接口适配:根据上述变化调整代码接口调用
  5. 事件重构:更新事件处理机制
  6. 资源调整:检查并调整资源管理方式
  7. 构建配置:迁移到 CMake 构建系统
  8. 测试验证:全面测试功能和性能

注意事项

  • 跨平台特性在 SOUI5 中需要额外适配工作
  • 图像解码器变更可能影响现有图片资源加载
  • 字符串使用方式变化需要全局搜索替换
  • 构建系统变更需要重新配置开发环境

常见问题

Q: 如何处理事件定义的迁移?

A: 将原有的 SEVENT_BEGIN_EX/SEVENT_END 替换为 DEF_EVT 宏,并使用相应的方法访问事件属性。

Q: 字符串格式化输出出现问题怎么办?

A: 在所有 printf 等格式化输出中,为 SStringA/SStringW 对象显式调用 .c_str() 方法。

Q: 私有资源无法访问怎么办?

A: 检查是否需要调用 EnablePrivateUiDef(TRUE) 来获取访问权限。

通过遵循本指南,您可以顺利完成从 SOUI3 到 SOUI5 的迁移,并享受新版本带来的跨平台支持和功能增强。