在前面的教程里,雖然圖片都放到了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里面的資源都是以skin\XXX.png 這種形式的,而設置了資源路徑到skin文件夾之后,就不需要skin前綴了,因此直接用XXX.png就可以訪問到skin路徑下的文件。
而SetResourceZip是將資源壓縮到zip文件里,有的小伙伴不想讓人發現資源,於是想弄個加密壓縮包,或者把壓縮包分成幾部分,這樣就不能直接解壓了。當然,還有各種各樣的方法可以讓人看不到資源文件。
但是Alberl早在《仿迅雷播放器教程 -- 提取exe資源(12)》就告訴了大家一種方法,不僅可以直接提取QQ的rdb文件,還可以提取迅雷的加密XAR文件,不管是加密的,還是分成幾部分的文件,都是可以快速提取出來的,重要的是,根本不需要一丁點黑客知識,也不需要花時間去研究rdb和XAR的格式,更不需要去破解密碼,直接點擊下鼠標就OK了。
所以如果還沒有去隱藏資源,但是又想這樣做的小伙伴們,Alberl的建議就是:如果能快速搞定加密和擾亂文件,那就無所謂了,如果不會這些,就沒必要花時間去弄了,因為阿貓阿狗拿了你的資源也干不了啥事,而高手的話,你那點小伎倆根本就難不倒他,小公司模仿你的軟件也威脅不了你,大公司也看不上你的軟件,所以從商業的角度,只是浪費時間而已。當然,如果你實在不想共享資源,那就去做吧 ~O(∩_∩)O~