在前面的教程里,虽然图片都放到了skin文件夹里,但是XML却都在外面,当XML比较多时,就不太好看啦,如下图:
所以需要整理一下,将XML也放入skin文件夹,这样exe的目录就简洁多了:
将XML放入skin文件夹后,代码也要跟着变化哦,在duilib的Demo里经常可以看到如下代码:
(其中SetResourcePath是设置资源的路径,包括XML和图片等各种资源;SetResourceZip是指资源都放到ListRes.zip文件里了。)
CPaintManagerUI::SetInstance(hInstance); CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin")); CPaintManagerUI::SetResourceZip(_T("ListRes.zip"));
而Alberl的教程中一直只有一行代码
CPaintManagerUI::SetInstance(hInstance);
这是因为WindowImplBase已经将CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath())封装到内部了,所以无需再调用,不过当我们将资源路径设置到skin文件夹时,却发现SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin"));后,程序会崩溃。这是因为需要重载WindowImplBase的GetSkinFolder函数,并且return _T("skin"),不过这就让那几个类都不通用了,显然不是个好方法,因此需要找一个通用的方法,那就是改进WindowImplBase,只需将WindowImplBase::OnCreate函数里的
CDialogBuilder builder; CDuiString strResourcePath=m_PaintManager.GetInstancePath(); strResourcePath+=GetSkinFolder().GetData(); m_PaintManager.SetResourcePath(strResourcePath.GetData());
改成下面这样即可:
CDialogBuilder builder; CDuiString strResourcePath=m_PaintManager.GetResourcePath(); if (strResourcePath.IsEmpty()) { strResourcePath=m_PaintManager.GetInstancePath(); strResourcePath+=GetSkinFolder().GetData(); } m_PaintManager.SetResourcePath(strResourcePath.GetData());
这样我们就可以像Demo里那样直接调用CPaintManagerUI::SetResourcePath函数啦,不过还需要将XML里面的资源路径改一下,因为XML里面的资源都是以skinXXX.png 这种形式的,而设置了资源路径到skin文件夹之后,就不需要skin前缀了,因此直接用XXX.png就可以访问到skin路径下的文件。
而SetResourceZip是将资源压缩到zip文件里,有的小伙伴不想让人发现资源,于是想弄个加密压缩包,或者把压缩包分成几部分,这样就不能直接解压了。当然,还有各种各样的方法可以让人看不到资源文件。
但是Alberl早在《仿迅雷播放器教程 -- 提取exe资源(12)》就告诉了大家一种方法,不仅可以直接提取QQ的rdb文件,还可以提取迅雷的加密XAR文件,不管是加密的,还是分成几部分的文件,都是可以快速提取出来的,重要的是,根本不需要一丁点黑客知识,也不需要花时间去研究rdb和XAR的格式,更不需要去破解密码,直接点击下鼠标就OK了。
所以如果还没有去隐藏资源,但是又想这样做的小伙伴们,Alberl的建议就是:如果能快速搞定加密和扰乱文件,那就无所谓了,如果不会这些,就没必要花时间去弄了,因为阿猫阿狗拿了你的资源也干不了啥事,而高手的话,你那点小伎俩根本就难不倒他,小公司模仿你的软件也威胁不了你,大公司也看不上你的软件,所以从商业的角度,只是浪费时间而已。当然,如果你实在不想共享资源,那就去做吧 ~O(∩_∩)O~