duilib : 做一个清除工程中废弃图片资源的工具
来源:互联网 发布:国泰安数据库价钱 编辑:程序博客网 时间:2024/04/30 08:02
问题原由
最近,工程基本完工. 还没有接到新的任务. 有时间整理一下工程.
前天发现工程中skin.zip中很多被废弃的图片资源.
注意到这个问题的原因,是因为这个工程有明确的size指标要求, 要求PE size必须<5MB. 减肥之前,已经超出了300KB.
产生废弃图片资源的原因是很多的:
* 工程本身是从上一版工程基础上直接改出来的, 因为UI需求不同,导致很多旧版的图片资源和xml留在了skin.zip中.
* 接受任务后,有很多要解决的当前问题。根本顾不上给程序减肥.
* 开发过程中,由多个同事一起开发。有些UI需求变更了之后,旧的图片资源当时没有被开发者去掉。再后来,就没人想起这件事.
思路
我解决这个问题的思路如下:
* 将skin.zip压缩前的图片资源目录,先手工确定一下,到底工程中用到了skin.zip中的哪些.xml ? 这一步需要手工确定. 将废弃的xml删除.
* 将程序中用c++代码指定的图片资源全部换成宏, 将这些宏全部放到一个.h中. e.g. const_define_picture_used_not_in_rc_xml.h
* 写一个工具程序,删除被废弃的图片资源.
自己感觉,写了这个工具,对已有dui工程减肥很有帮助. 减肥的工作量小多了, 工程也没有那么难伺候了~
工程下载点
编译环境
vs2010 vc++ console
工具程序的思路
* 遍历图片资源目录, 找出2个集合(xml文件名集合 + 图片文件名集合)
* 用图片文件名集每一个文件名遍历xml文件名集合和const_define_picture_used_not_in_rc_xml.h, 如果没有出现在这2个地方,说明该图片是一个被废弃的图片资源.
将收集到的废弃图片资源写进一个ini.
* 用户(我)自己进行手工确认. 如果错了,修改被废弃文件.ini. 这种情况没有发生.
* 用户(我)执行另外一个命令给定废弃图片.ini, 执行实际删除任务.
总结
工具的用法
prj-remove-trash-on-duilib-picture-resource.exe find-trash "F:\demo\prj-remove-trash-on-duilib-picture-resource\bin\dui-test" "F:\demo\prj-remove-trash-on-duilib-picture-resource\bin\const_define_picture_used_not_in_rc_xml.h"
delete-trash-by-ini "F:\demo\prj-remove-trash-on-duilib-picture-resource\bin\trash_pic_file_find.ini"
示例用的图片资源目录结构
| pic_test1.png| pic_test2.png| pic_test3.png| test.xml| trash10.png| trash11.png| trash12.png|\---sub-dir1 pic_test1.png trash1.png trash2.png trash3.png
工程中定义的图片资源文件名的头文件示例
/// @file const_define_picture_used_not_in_rc_xml.h/// @brief 设置此文件的目的 : /// 当整理工程时, 用 remove-pic-trash 扫描xml资源目录 \doc\UiDesignPrj\skin 和 本文件/// 用来找到在工程中和xml中都没有用到废弃图片资源#ifndef __CONST_DEFINE_PICTURE_USED_NOT_IN_RC_XML_H__#define __CONST_DEFINE_PICTURE_USED_NOT_IN_RC_XML_H__/// 没有在资源xml中使用的图片资源定义/// 图片资源定义前缀 : PIC_NAME_/// e.g. #define PIC_NAME_ L""#define PIC_NAME_pic_used_on_prj_001 L"pic_test1.png"#define PIC_NAME_pic_used_on_prj_002 L"pic_test2.png"#define PIC_NAME_pic_used_on_prj_003 L"pic_test3.png"#endif // #ifndef __CONST_DEFINE_PICTURE_USED_NOT_IN_RC_XML_H__
收集到的xml文件ini样例
[XmlFind]base_dir=D:\study\svn-rep-study\demo\duilib\prj-remove-trash-on-duilib-picture-resource\bin\dui-testcnt=1Item_0=test.xml
收集到的废弃图片资源ini样例
[TrashFind]base_dir=D:\study\svn-rep-study\demo\duilib\prj-remove-trash-on-duilib-picture-resource\bin\dui-testcnt=6Item_0=sub-dir1\trash1.pngItem_1=sub-dir1\trash2.pngItem_2=sub-dir1\trash3.pngItem_3=trash10.pngItem_4=trash11.pngItem_5=trash12.png
实现
#include "stdafx.h"#include <windows.h>#include <tchar.h>#include <Strsafe.h>#include <time.h>#include "const-define-remove-pic-trash.h"typedef struct _tag_cmd_line_param{ std::deque<std::wstring> deq_param; _tag_cmd_line_param() { clear(); } void clear() { deq_param.clear(); }}TAG_CMD_LINE_PARAM;int fnProcessCmd(int argc, _TCHAR* argv[]);void ShowUsage();void ShowUsage_CmdAction();void showDeque(IN std::deque<std::wstring>& deqPicUnusedPathName, IN const WCHAR* pcTip);void LogDequeToIniFile(IN std::deque<std::wstring>& deqPicUnusedPathName, IN const WCHAR* pcIniFile, IN const WCHAR* pcBaseDir, IN const WCHAR* pcTip);void LogDequeToIniFile_xml(IN std::deque<std::wstring>& deqPicUnusedPathName, IN const WCHAR* pcIniFile, IN const WCHAR* pcBaseDir, IN const WCHAR* pcTip);BOOL IsValidCmdAction(const WCHAR* pcCmdAction);int fnProcess_CMD_LINE_PARAM(IN TAG_CMD_LINE_PARAM& cmdLineParam);int fnProcessCmd_find_trash( IN const WCHAR* pcDir, IN const WCHAR* pcFileConstDefinePicUsedOnProject, OUT std::deque<std::wstring>& deqPicUnusedPathName);int find_and_append_file_type(const WCHAR* pcDir, const WCHAR* pcFileType, std::deque<std::wstring>& deqObj);int append_deque_wstring(std::deque<std::wstring>& deqDst, std::deque<std::wstring>& deqSrc, const WCHAR* pcSubDirName);int find_unused_pic( IN const WCHAR* pcDir, IN std::deque<std::wstring>& deqXmlTotal, IN std::deque<std::wstring>& deqPicTotal, IN const WCHAR* pcFileConstDefinePicUsedOnProject, OUT std::deque<std::wstring>& deqPicUnused);std::wstring convert_catalog_division_symbol(const WCHAR* pcContent);int delete_trash_file_by_ini(const WCHAR* pcIniFilePathName);BOOL find_used_pic_onXml( IN const WCHAR* pcXmlPathName, IN const WCHAR* pcPicPathName);int _tmain(int argc, _TCHAR* argv[]){ srand((unsigned)time( NULL )); ns_base::ComInit(); ns_base::GdiPlusInit(); _tprintf(L">> remove-pic-trash\r\n"); fnProcessCmd(argc, argv); _tprintf(L"<< remove-pic-trash\r\n"); ns_base::GdiPlusUnInit(); ns_base::ComUnInit(); _tprintf(L"END, press any key to quit\r\n"); getwchar(); return 0;}int fnProcessCmd(int argc, _TCHAR* argv[]){ BOOL bNeedShowUsage = TRUE; int iIndex = 0; TAG_CMD_LINE_PARAM cmdLineParam; do { _tprintf(L"argc = %d\r\n", argc); for (iIndex = 0; iIndex < argc; iIndex++) { _tprintf(L"argv[%d] = [%s]\r\n", iIndex, argv[iIndex]); cmdLineParam.deq_param.push_back(argv[iIndex]); } do { if (cmdLineParam.deq_param.size() < 2) break; if (IsValidCmdAction(cmdLineParam.deq_param[1].c_str())) { if (ns_base::StringCompare_equ(cmdLineParam.deq_param[1].c_str(), CMD_ACTION_TRASH_FIND)) { if (cmdLineParam.deq_param.size() < 4) break; /// find-trash "F:\demo\prj-remove-trash-on-duilib-picture-resource\bin\dui-test" "F:\demo\prj-remove-trash-on-duilib-picture-resource\bin\const_define_picture_used_not_in_rc_xml.h" if (ns_base::IsDirExist(cmdLineParam.deq_param[2].c_str()) && ns_base::IsFileExist(cmdLineParam.deq_param[3].c_str())) { bNeedShowUsage = FALSE; } } else if (ns_base::StringCompare_equ(cmdLineParam.deq_param[1].c_str(), CMD_ACTION_DELETE_TRASH_FILE_BY_INI)) { if (cmdLineParam.deq_param.size() < 3) break; /// delete-trash-by-ini "F:\demo\prj-remove-trash-on-duilib-picture-resource\bin\trash_pic_file_find.ini" if (ns_base::IsFileExist(cmdLineParam.deq_param[2].c_str())) bNeedShowUsage = FALSE; } } } while (0); if (bNeedShowUsage) { ShowUsage(); break; } fnProcess_CMD_LINE_PARAM(cmdLineParam); } while (0); return S_OK;}void ShowUsage(){ std::wstring strMsg = L""; strMsg = ns_base::StringFormatV( L"usage : remove-pic-trash.exe dir-full-path-name cmd-action\r\n" L"e.g. remove-pic-trash.exe \"d:\\temp\\pic-dir\" find-trash"); _tprintf(L"%s\r\n", strMsg.c_str()); ShowUsage_CmdAction();}void ShowUsage_CmdAction(){ int iIndex = 0; std::wstring strMsg = L""; strMsg = L"CmdAction list:\r\n"; do { if (NULL == g_pcCmdAction[iIndex]) break; strMsg += g_pcCmdAction[iIndex++]; strMsg += L"\r\n"; } while (1); _tprintf(L"%s\r\n", strMsg.c_str());}BOOL IsValidCmdAction(const WCHAR* pcCmdAction){ BOOL bRc = FALSE; int iIndex = 0; do { if (NULL == pcCmdAction) break; do { if (NULL == g_pcCmdAction[iIndex]) break; if (ns_base::StringCompare_equ(pcCmdAction, g_pcCmdAction[iIndex])) { bRc = TRUE; break; } iIndex++; } while (1); } while (0); return bRc;}int fnProcess_CMD_LINE_PARAM(IN TAG_CMD_LINE_PARAM& cmdLineParam){ std::wstring strIniPathName = L""; std::deque<std::wstring> deqPicUnusedPathName; _tprintf(L"maybe cost some time, please wait a moment...\r\n"); if (ns_base::StringCompare_equ(cmdLineParam.deq_param[1].c_str(), CMD_ACTION_TRASH_FIND)) { fnProcessCmd_find_trash( cmdLineParam.deq_param[2].c_str(), cmdLineParam.deq_param[3].c_str(), deqPicUnusedPathName); if (deqPicUnusedPathName.size() > 0) { /// 如果在xml中没有用到的图片太多了, 屏幕显示不下,有一部分显示内容被冲掉了 // showDeque(deqPicUnusedPathName, CMD_ACTION_TRASH_FIND); ns_base::GenerateTempFileNameOnSysTmpDir(strIniPathName); strIniPathName += L".ini"; LogDequeToIniFile(deqPicUnusedPathName, strIniPathName.c_str(), cmdLineParam.deq_param[2].c_str(), L"unused picture file save to"); } else { _tprintf(L"nice, all picture files are using on project or xml\r\n"); } } else if (ns_base::StringCompare_equ(cmdLineParam.deq_param[1].c_str(), CMD_ACTION_DELETE_TRASH_FILE_BY_INI)) { delete_trash_file_by_ini(cmdLineParam.deq_param[2].c_str()); } return S_OK;}int delete_trash_file_by_ini(const WCHAR* pcIniFilePathName){ int iIndex = 0; int iTrashItemCnt = 0; const DWORD dwLenBuf = 8 * 1024; WCHAR* pcBuf = new WCHAR[dwLenBuf]; CIni ini; std::wstring strBaseDir = L""; std::wstring strTrashFilePathName = L""; std::wstring strTemp = L""; LONGLONG llTrashFileSizeTotal = 0; do { if (!ns_base::IsFileExist(pcIniFilePathName)) break; ini.SetPathName(pcIniFilePathName); iTrashItemCnt = ini.GetInt(SECTION_TRASH_FIND, KEY_CNT, 0); pcBuf[0] = L'\0'; ini.GetString(SECTION_TRASH_FIND, KEY_FILE_BASE_DIR, pcBuf, dwLenBuf, L""); strBaseDir = pcBuf; if (!ns_base::IsStringLastCharMatch(strBaseDir.c_str(), L'\\')) { strBaseDir += L"\\"; } for (iIndex = 0; iIndex < iTrashItemCnt; iIndex++) { strTemp = ns_base::StringFormatV(L"%s%d", KEY_ITEM_NAME_PREFIX, iIndex); pcBuf[0] = L'\0'; ini.GetString(SECTION_TRASH_FIND, strTemp.c_str(), pcBuf, dwLenBuf, L""); if (_tcslen(pcBuf) > 0) { strTrashFilePathName = strBaseDir.c_str(); strTrashFilePathName += pcBuf; if (ns_base::IsFileExist(strTrashFilePathName.c_str())) { llTrashFileSizeTotal += ns_base::GetFileSize(strTrashFilePathName.c_str()); ns_base::DeleteFilePro(strTrashFilePathName.c_str()); } } } _tprintf(L"delete trash file %I64dKB, %dfiles\r\n", llTrashFileSizeTotal / 1024, iTrashItemCnt); } while (0); SAFE_DELETE_ARRAY(pcBuf); return S_OK;}void showDeque(IN std::deque<std::wstring>& deqPicUnusedPathName, IN const WCHAR* pcTip){ std::deque<std::wstring>::iterator it; _tprintf(L"%s\r\n", (NULL != pcTip) ? pcTip : L""); for (it = deqPicUnusedPathName.begin(); it != deqPicUnusedPathName.end(); it++) { _tprintf(L"%s\r\n", it->c_str()); } _tprintf(L"\r\n");}void LogDequeToIniFile_xml(IN std::deque<std::wstring>& deqPicUnusedPathName, IN const WCHAR* pcIniFile, IN const WCHAR* pcBaseDir, IN const WCHAR* pcTip){ CIni ini; int iPos = 0; std::deque<std::wstring>::iterator it; std::wstring strTemp = L""; std::wstring strIniFilePathName = (NULL != pcIniFile) ? pcIniFile : L"c:\\xml_find.ini"; ini.SetPathName(strIniFilePathName.c_str()); if (!ns_base::IsDirExist(pcBaseDir)) { _ASSERT_EXPR(0, L"!ns_base::IsDirExist(pcBaseDir)"); } ini.WriteString(SECTION_XML_FIND, KEY_FILE_BASE_DIR, pcBaseDir); strTemp = ns_base::StringFormatV(L"%d", deqPicUnusedPathName.size()); ini.WriteString(SECTION_XML_FIND, KEY_CNT, strTemp.c_str()); strTemp = ns_base::StringFormatV(L">> %s\r\n", (NULL != pcTip) ? pcTip : L""); _tprintf(strTemp.c_str()); for (it = deqPicUnusedPathName.begin(); it != deqPicUnusedPathName.end(); it++) { strTemp = ns_base::StringFormatV(L"%s%d", KEY_ITEM_NAME_PREFIX, iPos++); ini.WriteString(SECTION_XML_FIND, strTemp.c_str(), it->c_str()); } strTemp = ns_base::StringFormatV(L"<< %s\r\n", (NULL != pcTip) ? pcTip : L""); _tprintf(strTemp.c_str()); _tprintf(L"ini file save to : %s\r\n", strIniFilePathName.c_str());}void LogDequeToIniFile(IN std::deque<std::wstring>& deqPicUnusedPathName, IN const WCHAR* pcIniFile, IN const WCHAR* pcBaseDir, IN const WCHAR* pcTip){ CIni ini; int iPos = 0; std::deque<std::wstring>::iterator it; std::wstring strTemp = L""; std::wstring strIniFilePathName = (NULL != pcIniFile) ? pcIniFile : L"c:\\trash_find.ini"; ini.SetPathName(strIniFilePathName.c_str()); if (!ns_base::IsDirExist(pcBaseDir)) { _ASSERT_EXPR(0, L"!ns_base::IsDirExist(pcBaseDir)"); } ini.WriteString(SECTION_TRASH_FIND, KEY_FILE_BASE_DIR, pcBaseDir); strTemp = ns_base::StringFormatV(L"%d", deqPicUnusedPathName.size()); ini.WriteString(SECTION_TRASH_FIND, KEY_CNT, strTemp.c_str()); strTemp = ns_base::StringFormatV(L">> %s\r\n", (NULL != pcTip) ? pcTip : L""); _tprintf(strTemp.c_str()); for (it = deqPicUnusedPathName.begin(); it != deqPicUnusedPathName.end(); it++) { strTemp = ns_base::StringFormatV(L"%s%d", KEY_ITEM_NAME_PREFIX, iPos++); ini.WriteString(SECTION_TRASH_FIND, strTemp.c_str(), it->c_str()); } strTemp = ns_base::StringFormatV(L"<< %s\r\n", (NULL != pcTip) ? pcTip : L""); _tprintf(strTemp.c_str()); _tprintf(L"ini file save to : %s\r\n", strIniFilePathName.c_str());}int fnProcessCmd_find_trash( IN const WCHAR* pcDir, IN const WCHAR* pcFileConstDefinePicUsedOnProject, OUT std::deque<std::wstring>& deqPicUnusedPathName){ std::wstring strBaseDir = L""; std::wstring strIniPathName = L""; std::deque<std::wstring> deqXml; std::deque<std::wstring> deqPic; strBaseDir = pcDir; if (!ns_base::IsStringLastCharMatch(strBaseDir.c_str(), L'\\')) { strBaseDir += L"\\"; } find_and_append_file_type(strBaseDir.c_str(), L".xml", deqXml); ns_base::GenerateTempFileNameOnSysTmpDir(strIniPathName); strIniPathName += L".ini"; LogDequeToIniFile_xml(deqXml, strIniPathName.c_str(), pcDir, L"xml files find, save to"); find_and_append_file_type(strBaseDir.c_str(), L".bmp", deqPic); find_and_append_file_type(strBaseDir.c_str(), L".gif", deqPic); find_and_append_file_type(strBaseDir.c_str(), L".jpg", deqPic); find_and_append_file_type(strBaseDir.c_str(), L".png", deqPic); find_unused_pic( strBaseDir.c_str(), deqXml, deqPic, pcFileConstDefinePicUsedOnProject, deqPicUnusedPathName); return S_OK;}int find_unused_pic(IN const WCHAR* pcDir, IN std::deque<std::wstring>& deqXmlTotal, IN std::deque<std::wstring>& deqPicTotal, IN const WCHAR* pcFileConstDefinePicUsedOnProject, OUT std::deque<std::wstring>& deqPicUnused){ BOOL bPicUsedOnAnyPic = FALSE; std::deque<std::wstring>::iterator itXml; std::deque<std::wstring>::iterator itPic; std::wstring strXmlPathNameBase = L""; std::wstring strXmlPathName = L""; std::wstring strContent_FileConstDefinePicUsedOnProject = L""; std::wstring strConvert = L""; std::wstring strTemp = L""; if (ns_base::IsFileExist(pcFileConstDefinePicUsedOnProject)) { ns_base::ReadFromFileAsUnicodeText(pcFileConstDefinePicUsedOnProject, strContent_FileConstDefinePicUsedOnProject); } strXmlPathNameBase = pcDir; if (!ns_base::IsStringLastCharMatch(strXmlPathNameBase.c_str(), L'\\')) strXmlPathNameBase += L"\\"; deqPicUnused.clear(); for (itPic = deqPicTotal.begin(); itPic != deqPicTotal.end(); itPic++) { bPicUsedOnAnyPic = FALSE; for (itXml = deqXmlTotal.begin(); itXml != deqXmlTotal.end(); itXml++) { strXmlPathName = strXmlPathNameBase.c_str(); strXmlPathName += itXml->c_str(); if (!ns_base::IsFileExist(strXmlPathName.c_str())) { _ASSERT_EXPR(0, L"xml not find"); } if (find_used_pic_onXml(strXmlPathName.c_str(), itPic->c_str())) { bPicUsedOnAnyPic = TRUE; break; } } if (!bPicUsedOnAnyPic) { /// 在工程中定义的宏'\'为"\\" /// e.g. #define PIC_NAME_some_btn_n L"dir_on_xml_rc\\some_btn_n.png" /// 查找之前,要先将'\'转成.h中定义的格式'\\' strConvert = convert_catalog_division_symbol(itPic->c_str()); /// 格式化成.h中需要的样式 "dir_on_xml_rc\\some_btn_n.png" strTemp = ns_base::StringFormatV(L"\"%s\"", strConvert.c_str()); if (std::wstring::npos == strContent_FileConstDefinePicUsedOnProject.find(strTemp.c_str())) { /// 找到没有在xml中使用的图片资源文件, 也没有在我们工程中被定义和使用 /// 那这个图片资源文件就是被废弃的. deqPicUnused.push_back(itPic->c_str()); } } } return S_OK;}std::wstring convert_catalog_division_symbol(const WCHAR* pcContent){ std::wstring strOut = L""; size_t nLen = 0; size_t nIndex = 0; WCHAR cNow = L'\0'; do { if (NULL == pcContent) break; nLen = _tcslen(pcContent); for (nIndex = 0; nIndex < nLen; nIndex++) { cNow = *(pcContent + nIndex); if (L'\\' == cNow) { strOut += L"\\\\"; } else { strOut += cNow; } } } while (0); return strOut;}BOOL find_used_pic_onXml( IN const WCHAR* pcXmlPathName, IN const WCHAR* pcPicPathName){ BOOL bRc = FALSE; UCHAR* pcFileData = NULL; DWORD dwDataLen = 0; LONGLONG llFileSize = 0; std::wstring strFileContent = L""; do { llFileSize = ns_base::GetFileSize(pcXmlPathName); if (llFileSize <= 0) break; dwDataLen = (DWORD)llFileSize; if (!ns_base::ReadFromFile(pcXmlPathName, pcFileData, dwDataLen)) { pcFileData = new UCHAR[dwDataLen + 1]; ::ZeroMemory(pcFileData, dwDataLen + 1); } if (!ns_base::ReadFromFile(pcXmlPathName, pcFileData, dwDataLen)) { break; } strFileContent = ns_base::A2Wex((const char*)pcFileData); bRc = (std::wstring::npos != strFileContent.find(pcPicPathName)); } while (0); return bRc;}int find_and_append_file_type(const WCHAR* pcDir, const WCHAR* pcFileType, std::deque<std::wstring>& deqObj){ int iRc = S_OK; int iLenL = 0; int iLenR = 0; HANDLE hFind = NULL; WIN32_FIND_DATAW wfd; std::wstring strDirCur = L""; std::wstring strFindFilter = L""; std::wstring strTemp = L""; std::wstring::size_type nPos = 0; std::deque<std::wstring> deqTemp; do { if (!ns_base::IsDirExist(pcDir) || (NULL == pcFileType) || (_tcslen(pcFileType) <= 0)) { break; } strFindFilter = pcDir; if (!ns_base::IsStringLastCharMatch(strFindFilter.c_str(), L'\\')) { strFindFilter += L"\\"; } strDirCur = strFindFilter.c_str(); strFindFilter += L"*.*"; hFind = FindFirstFile(strFindFilter.c_str(), &wfd); if (INVALID_HANDLE_VALUE == hFind) { iRc = S_FALSE; break; } do { if ((0 == _tcscmp(wfd.cFileName, _T("."))) || (0 == _tcscmp(wfd.cFileName, _T("..")))) { continue; } if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { strTemp = strDirCur.c_str(); strTemp += wfd.cFileName; deqTemp.clear(); find_and_append_file_type(strTemp.c_str(), pcFileType, deqTemp); if (deqTemp.size() > 0) { append_deque_wstring(deqObj, deqTemp, wfd.cFileName); } } strTemp = wfd.cFileName; nPos = strTemp.rfind(pcFileType); iLenL = _tcslen(strTemp.c_str()); iLenR = nPos + _tcslen(pcFileType); if ((std::wstring::npos == nPos) || (iLenL != iLenR)) { continue; } deqObj.push_back(strTemp); } while (FindNextFile(hFind, &wfd)); FindClose(hFind); iRc = S_OK; } while (0); return iRc;}int append_deque_wstring(std::deque<std::wstring>& deqDst, std::deque<std::wstring>& deqSrc, const WCHAR* pcSubDirName){ std::deque<std::wstring>::iterator it; std::wstring strSubDirName = (NULL != pcSubDirName) ? pcSubDirName : L""; std::wstring strTemp = L""; if ((strSubDirName.size() > 0) && !ns_base::IsStringLastCharMatch(strSubDirName.c_str(), L'\\')) { strSubDirName += L"\\"; } for (it = deqSrc.begin(); it != deqSrc.end(); it++) { strTemp = strSubDirName.c_str(); strTemp += it->c_str(); deqDst.push_back(strTemp.c_str()); } return S_OK;}
- duilib : 做一个清除工程中废弃图片资源的工具
- duilib做的一个程序
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源(转)
- 清除Android工程中没用到/未用到的资源
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源
- Android清除工程中无用的资源文件
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源
- 清除Android工程中没用到的资源
- 清除其他废弃的MV
- 清除IOS项目中无用的图片资源
- 清除IOS项目中无用的图片资源
- 一个可以查询工程未使用的图片资源脚本!
- Leetcode-median of two sorted arrays
- 2015-05-06python-web攻略(1)套接字-IPv4-简单的客户端服务器编程
- 灰度图像的对比度动态范围压缩
- php使用curl发起http请求
- 解读高指数下的投资机会
- duilib : 做一个清除工程中废弃图片资源的工具
- Android使用ViewPager实现左右切换(转)
- 代码控制数据流量开关
- 在Windows7系统下装Linux双系统探索历程
- 构建自己的AngularJS,第一部分:Scope和Digest
- android保存文件到手机内存
- JavaScript 基本数据类型 与类型检测
- 用代码实现来电拦截
- 线性表算法-插入