SOUI总结之简介
简介
uires.idx:定义资源索引
init.xml:定义全局 UI 的属性,包含字体,字符串表,skin,style,objattr,参见前篇介绍。
dlg_main.xml:主窗口XML。
关于 XML 定义的大概顺序是:
1:资源引入
uires.idx (这里定义界面要使用的一些资源)
格式:
<资源类型>
Name = 资源自定义名称, path=资源路径
</资源类型>
2:定义全局变量
init.xml (这里定义全局变量并用资源初始化这些全局变量)
格式:
<变量类型>
Name=变量名称, src=资源类型:资源别名, 控件属性...
</变量类型>
3: 使用全局变量
dlg_main.xml(这里开始引用上面的变量)
这个 xml_init 必须是以 UIDEF 为唯一根节点。
在 UIDEF 下,可以定义 font,string,skins,style,objattr 五个子节点。
其中,font 定义 SOUI 中使用的默认字体,只有 face 和 size 两个属性。
string 是一个字符串表,定义一个"name-字符串"映射,在布局的 XML 文件中可以通过
引用字符串的 name 来获得字符串。
系统资源管理
上一节,我们已经讲到在 SOUI 中所有资源文件通过一个 uires.idx 文件进行索引。
这里将介绍在程序中如何引用这些资源文件。
在 SOUI 系统中,资源文件通过一个统一的接口对象读取:
namespace SOUI
{
enum BUILTIN_RESTYPE
{
RES_PE=0,
RES_FILE,
};
/**
* @struct IResProvider
* @brief ResProvider 对象
*
* Describe 实现各种资源的加载
*/
struct IResProvider : public IObjRef
{
/**
* Init
* @brief 资源初始化函数
* @param WPARAM wParam -- param 1
* @param LPARAM lParam -- param 2
* @return BOOL -- true:succeed
*
* Describe every Resprovider must implement this interface.
*/
virtual BOOL Init(WPARAM wParam,LPARAM lParam) =0;
/**
* HasResource
* @brief 查询一个资源是否存在
* @param LPCTSTR strType -- 资源类型
* @param LPCTSTR pszResName -- 资源名称
* @return BOOL -- true 存在,false 不存在
* Describe
*/
virtual BOOL HasResource(LPCTSTR strType,LPCTSTR pszResName)=0;
/**
* LoadIcon
* @brief 从资源中加载 ICON
* @param LPCTSTR pszResName -- ICON 名称
* @param int cx -- ICON 宽度
* @param int cy -- ICON 高度
* @return HICON -- 成功返回 ICON 的句柄,失败返回 0
* Describe
*/
virtual HICON LoadIcon(LPCTSTR pszResName,int cx=0,int cy=0)=0;
/**
* LoadBitmap
43
* @brief 从资源中加载 HBITMAP
* @param LPCTSTR pszResName -- BITMAP 名称
* @return HBITMAP -- 成功返回 BITMAP 的句柄,失败返回 0
* Describe
*/
virtual HBITMAP LoadBitmap(LPCTSTR pszResName)=0;
/**
* LoadCursor
* @brief 从资源中加载光标
* @param LPCTSTR pszResName -- 光标名
* @return HCURSOR -- 成功返回光标的句柄,失败返回 0
* Describe 支持动画光标
*/
virtual HCURSOR LoadCursor(LPCTSTR pszResName)=0;
/**
* LoadImage
* @brief 从资源加载一个 IBitmap 对象
* @param LPCTSTR strType -- 图片类型
* @param LPCTSTR pszResName -- 图片名
* @return IBitmap * -- 成功返回一个 IBitmap 对象,失败返回 0
* Describe 如果没有定义 strType,则根据 name 使用 FindImageType 自动查找匹配
的类型
*/
virtual IBitmap * LoadImage(LPCTSTR strType,LPCTSTR pszResName)=0;
/**
* LoadImgX
* @brief 从资源中创建一个 IImgX 对象
* @param LPCTSTR strType -- 图片类型
* @param LPCTSTR pszResName -- 图片名
* @return IImgX * -- 成功返回一个 IImgX 对象,失败返回 0
* Describe
*/
virtual IImgX * LoadImgX(LPCTSTR strType,LPCTSTR pszResName)=0;
/**
* GetRawBufferSize
* @brief 获得资源数据大小
* @param LPCTSTR strType -- 资源类型
* @param LPCTSTR pszResName -- 资源名
* @return size_t -- 资源大小(byte),失败返回 0
* Describe
*/
virtual size_t GetRawBufferSize(LPCTSTR strType,LPCTSTR pszResName)=0;
/**
* GetRawBuffer
* @brief 获得资源内存块
* @param LPCTSTR strType -- 资源类型
* @param LPCTSTR pszResName -- 资源名
* @param LPVOID pBuf -- 输出内存块
* @param size_t size -- 内存大小
* @return BOOL -- true 成功
* Describe 应该先用 GetRawBufferSize 查询资源大小再分配足够空间
*/
virtual BOOL GetRawBuffer(LPCTSTR strType,LPCTSTR pszResName,LPVOID
pBuf,size_t size)=0;
/**
* FindImageType
* @brief 查询与指定名称匹配的资源类型
* @param LPCTSTR pszImgName -- 资源名称
* @return LPCTSTR -- 资源类型,失败返回 NULL
* Describe 没有指定图片类型时默认从这些类别中查找
*/
virtual LPCTSTR FindImageType(LPCTSTR pszImgName) =0;
};
/**
* Helper_FindImageType
* @brief 查询与指定名称匹配的资源类型
* @param IResProvider * pResProvider -- 当前的 ResProvider
* @param LPCTSTR pszImgName -- 资源名称
* @return LPCTSTR -- 资源类型,失败返回 NULL
* Describe 提供一个公共的辅助函数
*/
}//namespace SOUI
这个接口的实现类通过实现这些既定接口来完成图标(HICON),光标(HCURSOR),位图
(HBITMAP),一般图片(IBitmap)的解码,同时也提供原始数据(RawData)的读取。
在 SOUI 系统中内置了两种类型的资源加载(ResProvider)模块:SResProviderPE 和
SResProviderFiles,同时也通过外置组件的形式提供了从 ZIP 文件加载资源的功能。
这三种资源加载方式基本上涵盖了目前常见的资源加载方式。
为了能够从 PE 的资源数据段中加载资源,我们需要将 uires.idx 中索引的文件转换成 PE
资源可以识别的资源类型+资源名(不是资源 ID)的形式。
为了达到这个目的,我们只需要在 VS 的资源文件中(.rc)将 SOUI 的资源中定义的文件
按照 uires.idx 定义的类型和名称加进去即可。
手工添加资源文件很难保证不写错。为此,我提供了一个工具
(tools\uiresbuilder.exe),这个工具接收一组命令参数,用来将 uires.idx 转换成一个
RC 编译器可以识别的.rc2 文件(命令行参见使用向导生成的工程)。要编译该.rc2 文件,
需要在.rc 的资源包含中加上我们生成的.rc2 文件。
如果程序中的资源不从 PE 资源加载,则不需要编译 soui_res.rc2 文件,以减少程序体
积。
SResProviderPE, SResProviderFiles 和 SResProviderZIP 分别从 PE 资源,文件夹及
ZIP 文件包中初始化资源:
#if (RES_TYPE == 0)//从文件加载
CreateResProvider(RES_FILE,(IObjRef**)&pResProvider);
if(!pResProvider->Init((LPARAM)_T("uires"),0))
{
SASSERT(0);
return 1;
}
#elif (RES_TYPE==1)//从 EXE 资源加载
CreateResProvider(RES_PE,(IObjRef**)&pResProvider);
pResProvider->Init((WPARAM)hInstance,0);
#elif (RES_TYPE==2)//从 ZIP 包加载
bLoaded=pComMgr->CreateResProvider_ZIP((IObjRef**)&pResProvider);
SASSERT_FMT(bLoaded,_T("load interface [%s]
failed!"),_T("resprovider_zip"));
ZIPRES_PARAM param;
param.ZipFile(pRenderFactory, _T("uires.zip"),"souizip");
bLoaded = pResProvider->Init((WPARAM)¶m,0);
SASSERT(bLoaded);
#endif
资源加载成功后,调用 SApplication::AddResProvider(IResProvider *)接口将创建的资
源加载器交给 SOUI 系统管理。
SApplication::AddResProvider 可以调用多次,便于加载不同的资源。
资源加载后不再需要了也可以使用 SApplication::RemoveResProvider(IResProvider *)
来删除。
程序中要使用一个资源时,首先调用 SApplication::HasResource 来查询一个资源是否存
在,然后再根据资源类型选择不同的接口加载资源。
SApplication 中管理着一个 IResProvider 列表,系统采用后进先查的算法处理资源重
名,即最后调用 AddResProvider 加进来的资源加载器优先级最高。
————————————————
版权声明:本文为CSDN博主「自由职业梦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zym648326374/article/details/129966422
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了