给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完成,