给duilib添加import标签功能,导入其它xml文件
版权声明:
本文为博主原创文章,转载请声明原文链接...谢谢。o_0。
更新时间:
2017-11-29 19:06:58
温馨提示:
学无止境,技术类文章有它的时效性,请留意文章更新时间,如发现内容有误请留言指出,防止别人"踩坑",我会及时更新文章
因为duilib中已经使用啦include这个标签。所有起名字就起为import啦。实现duilib解析xml前把引入的其它xml的内容包含进来。实现这样的功能需要改动的文件在 UIMarkup.cpp ,UIMarkup.cpp 中传入的xml字符串或文件路径都是在这里面判断并加载的。在这个类解析xml字符串之前实现这个字符串引入替换就可以啦。
UIDlgBuilder.cpp中有这样的代码
判断是字符串还是文件路径。而m_xml类型是UImarkup类型。这里分别调用啦load和loadFromFile。在这个类里我们还要添加一个函数,递归解析字符串里包含import标签
在UIMarkup.h中添加下面两个函数的声明
TCHAR* _ParseImport(const TCHAR* xmlstr,DWORD dwSize); BYTE* _LoadFromFile(LPCTSTR pstrFilename, int encoding, DWORD& dwSize);
然后UIMarkup.cpp中添加主体
TCHAR * CMarkup::_ParseImport(const TCHAR * xmlstr, DWORD dwSize) { char *srcXml = new char[dwSize + 1]{ 0 }; #ifdef _UNICODE memcpy(srcXml, (char*)xmlstr, dwSize); #else memcpy(srcXml, xmlstr, dwSize); #endif //import标签字符串 char imxml[256] = { 0 }; //查找<import指针 char* pim = strstr(srcXml, "<Import"); //临时字符串 char tems[2] = { 0 }; //循环次数 int jishu = 0; //取出import标签 if (pim != NULL) { memcpy(tems, pim, 1); while (strcmp(tems, "/") != 0) { memcpy(imxml + jishu, tems, 1); jishu++; //取下一个字符 memcpy(tems, pim + jishu, 1); } //加上结尾的两个字符 memcpy(imxml + jishu, "/>", 2); } else { return NULL; } //取包含文件的路径 char filepath[256] = { 0 }; char* pfil = strstr(imxml, "file=\""); if (pfil != NULL) { pfil = pfil + strlen("file=\""); jishu = 0; memcpy(tems, pfil + jishu, 1); while (strcmp(tems, "\"") != 0) { memcpy(filepath + jishu, tems, 1); jishu++; //取下一个字符 memcpy(tems, pfil + jishu, 1); } } DWORD fileSize = 0; #ifdef _UNICODE DWORD dwNum1 = MultiByteToWideChar(CP_ACP, 0, filepath, -1, NULL, 0); wchar_t* pwText = new wchar_t[dwNum1]; MultiByteToWideChar(CP_ACP, 0, filepath, -1, pwText, dwNum1); BYTE* pByte = _LoadFromFile(pwText, XMLFILE_ENCODING_UTF8, fileSize); delete[] pwText; #else BYTE* pByte = _LoadFromFile(filepath, XMLFILE_ENCODING_UTF8, fileSize); #endif char* xs = new char[fileSize + 1]{ 0 }; memcpy(xs, pByte, fileSize); delete[]pByte; //替换字符串 char *newstr = new char[fileSize + strlen(srcXml) + 10]{ 0 }; pim[0] = '\0'; strcat(newstr, srcXml); if (xs != NULL) { strcat(newstr, xs); delete[] xs; xs = NULL; } strcat(newstr, pim + strlen(imxml)); delete[] srcXml; srcXml = NULL; char* xhstr = (char*)_ParseImport((TCHAR*)newstr, strlen(newstr)); char* reData = NULL; if (xhstr == NULL) { reData= newstr; newstr = NULL; } else { //返回递归解析出来的字符串 delete[] newstr; reData= xhstr; xhstr = NULL; } return (TCHAR*)reData; } BYTE* CMarkup::_LoadFromFile(LPCTSTR pstrFilename, int encoding, DWORD& dwSize) { Release(); CDuiString sFile = CPaintManagerUI::GetResourcePath(); if (CPaintManagerUI::GetResourceZip().IsEmpty()) { sFile += pstrFilename; HANDLE hFile = ::CreateFile(sFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return NULL; dwSize = ::GetFileSize(hFile, NULL); if (dwSize == 0) return NULL; if (dwSize > 4096 * 1024) return NULL; DWORD dwRead = 0; BYTE* pByte = new BYTE[dwSize]; ::ReadFile(hFile, pByte, dwSize, &dwRead, NULL); ::CloseHandle(hFile); if (dwRead != dwSize) { delete[] pByte; Release(); return NULL; } //bool ret = LoadFromMem(pByte, dwSize, encoding); //delete[] pByte; return pByte; } else { sFile += CPaintManagerUI::GetResourceZip(); HZIP hz = NULL; if (CPaintManagerUI::IsCachedResourceZip()) hz = (HZIP)CPaintManagerUI::GetResourceZipHandle(); else hz = OpenZip((void*)sFile.GetData(), 0, 2); if (hz == NULL) return NULL; ZIPENTRY ze; int i; if (FindZipItem(hz, pstrFilename, true, &i, &ze) != 0) return NULL; dwSize = ze.unc_size; if (dwSize == 0) return NULL; if (dwSize > 4096 * 1024) return NULL; BYTE* pByte = new BYTE[dwSize]; int res = UnzipItem(hz, i, pByte, dwSize, 3); if (res != 0x00000000 && res != 0x00000600) { delete[] pByte; if (!CPaintManagerUI::IsCachedResourceZip()) CloseZip(hz); return NULL; } if (!CPaintManagerUI::IsCachedResourceZip()) CloseZip(hz); //bool ret = LoadFromMem(pByte, dwSize, encoding); //delete[] pByte; return pByte; } }
最后修改原版带的 Loadfromfile函数为下面的格式
bool CMarkup::LoadFromFile(LPCTSTR pstrFilename, int encoding) { DWORD dwSize = 0; BYTE* pByte = _LoadFromFile(pstrFilename, encoding, dwSize); if (pByte != NULL) { TCHAR* stem = _ParseImport((TCHAR*)pByte, dwSize); if (stem != NULL) { delete[] pByte; DWORD fsize = strlen((char*)stem); BYTE* pb = new BYTE[fsize]{ 0 }; memcpy(pb, stem, fsize); bool ret = LoadFromMem(pb, fsize, encoding); delete[]pb; delete[] stem; return ret; } else { bool ret = LoadFromMem(pByte, dwSize, encoding); delete[] pByte; return ret; } } else { return false; } //Release(); //CDuiString sFile = CPaintManagerUI::GetResourcePath(); //if( CPaintManagerUI::GetResourceZip().IsEmpty() ) { // sFile += pstrFilename; // HANDLE hFile = ::CreateFile(sFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // if( hFile == INVALID_HANDLE_VALUE ) return _Failed(_T("Error opening file")); // DWORD dwSize = ::GetFileSize(hFile, NULL); // if( dwSize == 0 ) return _Failed(_T("File is empty")); // if ( dwSize > 4096*1024 ) return _Failed(_T("File too large")); // DWORD dwRead = 0; // BYTE* pByte = new BYTE[ dwSize ]; // ::ReadFile( hFile, pByte, dwSize, &dwRead, NULL ); // ::CloseHandle( hFile ); // if( dwRead != dwSize ) { // delete[] pByte; // Release(); // return _Failed(_T("Could not read file")); // } // bool ret = LoadFromMem(pByte, dwSize, encoding); // delete[] pByte; // return ret; //} //else { // sFile += CPaintManagerUI::GetResourceZip(); // HZIP hz = NULL; // if( CPaintManagerUI::IsCachedResourceZip() ) hz = (HZIP)CPaintManagerUI::GetResourceZipHandle(); // else hz = OpenZip((void*)sFile.GetData(), 0, 2); // if( hz == NULL ) return _Failed(_T("Error opening zip file")); // ZIPENTRY ze; // int i; // if( FindZipItem(hz, pstrFilename, true, &i, &ze) != 0 ) return _Failed(_T("Could not find ziped file")); // DWORD dwSize = ze.unc_size; // if( dwSize == 0 ) return _Failed(_T("File is empty")); // if ( dwSize > 4096*1024 ) return _Failed(_T("File too large")); // BYTE* pByte = new BYTE[ dwSize ]; // int res = UnzipItem(hz, i, pByte, dwSize, 3); // if( res != 0x00000000 && res != 0x00000600) { // delete[] pByte; // if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz); // return _Failed(_T("Could not unzip file")); // } // if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz); // bool ret = LoadFromMem(pByte, dwSize, encoding); // delete[] pByte; // return ret; //} }
上面已经修改好啦加载文件时的解析,如果传的是字符串也要解析出里面的标签,需要修改load函数为下面格式
bool CMarkup::Load(LPCTSTR pstrXML) { //Release(); //SIZE_T cchLen = _tcslen(pstrXML) + 1; //m_pstrXML = static_cast<LPTSTR>(malloc(cchLen * sizeof(TCHAR))); //::CopyMemory(m_pstrXML, pstrXML, cchLen * sizeof(TCHAR)); //bool bRes = _Parse(); //if( !bRes ) Release(); //return bRes; //2017.11.29 mokuyu 添加 import标签 Release(); TCHAR *pstrNew = _ParseImport(pstrXML, _tcslen(pstrXML)); if (pstrNew != NULL) { SIZE_T cchLen = _tcslen(pstrNew) + 1; m_pstrXML = static_cast<LPTSTR>(malloc(cchLen * sizeof(TCHAR))); ::CopyMemory(m_pstrXML, pstrNew, cchLen * sizeof(TCHAR)); bool bRes = _Parse(); if (!bRes) Release(); return bRes; } else { SIZE_T cchLen = _tcslen(pstrXML) + 1; m_pstrXML = static_cast<LPTSTR>(malloc(cchLen * sizeof(TCHAR))); ::CopyMemory(m_pstrXML, pstrXML, cchLen * sizeof(TCHAR)); bool bRes = _Parse(); if (!bRes) Release(); return bRes; } }
ok完成,