主题:关于加载skin失败

admin 2018年12月08日 88

经常有网友在群里发下面类似的图片。 

 然后说在uires.idx, skin.xml里都已经配置好了。

为什么就是加载skin失败。 

差不多是每天一问了。 

要搞明白这个问题首先搞明白SOUI的资源加载方法。 

SOUI内置了两种资源加载方式,从PE资源加载及从文件夹加载。

另外还使用两个外部组件实现了从zip, 7z包加载资源的方式。 

出现这个问题主要是因为使用了PE资源加载方式。

这种方式下所有APP中用到的资源都编译到EXE中。

好处就是这个EXE可以单独运行,坏处就是这个EXE可能要经常重新编译。 

可能有的人到现在还不知道代码中使用的soui_res.rc2这个文件是干什么的。

 这个文件是使用uiresbuilder.exe这个工具生成的。

打开这个文件可以看到一系列的宏定义:

//stamp:01d359560e2f096a
/*<------------------------------------------------------------------------------------------------->*/
/*该文件由uiresbuilder生成,请不要手动修改*/
/*<------------------------------------------------------------------------------------------------->*/
#define DEFINE_UIRES(name, type, file_path)\
    name type file_path

DEFINE_UIRES(xml_init,        UIDEF,        "uires\\uidef\\init.xml")
DEFINE_UIRES(string,        values,        "uires\\values\\string.xml")
DEFINE_UIRES(color,        values,        "uires\\values\\color.xml")
DEFINE_UIRES(skin,        values,        "uires\\values\\skin.xml")
DEFINE_UIRES(ICON_0,        ICON,        "uires\\image\\img_logo.ico")
DEFINE_UIRES(ICON_LOGO,        ICON,        "uires\\image\\img_logo.ico")
DEFINE_UIRES(ICON_MM_ONLINE,        ICON,        "uires\\image\\MM\\imonline.ico")
DEFINE_UIRES(ICON_MM_OFFLINE,        ICON,        "uires\\image\\mm\\offline.ico")
DEFINE_UIRES(ICON_Loading1,        ICON,        "uires\\image\\32\\loading_1.ico")
DEFINE_UIRES(ICON_Loading2,        ICON,        "uires\\image\\32\\loading_2.ico")
DEFINE_UIRES(ICON_Loading3,        ICON,        "uires\\image\\32\\loading_3.ico")
DEFINE_UIRES(ICON_Loading4,        ICON,        "uires\\image\\32\\loading_4.ico")
DEFINE_UIRES(ICON_Loading5,        ICON,        "uires\\image\\32\\loading_5.ico")
DEFINE_UIRES(ICON_Loading6,        ICON,        "uires\\image\\32\\loading_6.ico")
DEFINE_UIRES(ANI_ARROW,        CURSOR,        "uires\\image\\021.ani")
DEFINE_UIRES(CUR_TST,        CURSOR,        "uires\\image\\camera_capture.cur")
DEFINE_UIRES(menu_test,        SMENU,        "uires\\xml\\menu_test.xml")
DEFINE_UIRES(menu_lv,        SMENU,        "uires\\xml\\menu_lv.xml")


比如上面从demos/demo/res/soui_res.rc2里截取的一段代码。

 这里有3个部分:

 第一行是一个时间stamp,用来记录每一个资源文件的修改总时间。在使用uiresbuilder编译uires.idx时都会检查这个时间,如果有修改才会更新这个.rc2文件。 

第二部分是那个DEFINE_UIRES这个宏,使用这个宏来标记一个资源文件。 

第三部分就是文件列表,和uires.idx里的文件一一对应。

soui_res.rc2在哪里用到呢?

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#pragma code_page(936)
#include "res\soui_res.rc2" //SOUI资源
#endif

这是demos/demo/demo.rc的最后几行,可以看到在这里包含了soui_res.rc2,SOUI的资源就是通过这里编译到EXE里去的。但是这里有个问题,soui_res.rc2修改后直接编译exe,资源通道不会自动重新编译。这也就直接导致了运行时找不到新增加的皮肤等资源。

要解决这个问题很简单,就是在.rc文件的右键菜单上选择编译一下就好了(当然前提是soui_res.rc2已经重新生成)。在.rc编译后,再编译EXE就可以找到新增加的皮肤了。