给duilib添加import标签功能,导入其它xml文件

来源:赵克立博客 分类: DuiLib 标签:duilib发布时间:2017-11-29 13:42:27最后更新:2017-11-29 19:06:58浏览:2161
版权声明:
本文为博主原创文章,转载请声明原文链接...谢谢。o_0。
更新时间:
2017-11-29 19:06:58
温馨提示:
学无止境,技术类文章有它的时效性,请留意文章更新时间,如发现内容有误请留言指出,防止别人"踩坑",我会及时更新文章

因为duilib中已经使用啦include这个标签。所有起名字就起为import啦。实现duilib解析xml前把引入的其它xml的内容包含进来。实现这样的功能需要改动的文件在 UIMarkup.cpp  ,UIMarkup.cpp 中传入的xml字符串或文件路径都是在这里面判断并加载的。在这个类解析xml字符串之前实现这个字符串引入替换就可以啦。

UIDlgBuilder.cpp中有这样的代码

image.png

判断是字符串还是文件路径。而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完成,


微信号:kelicom QQ群:215861553 紧急求助须知
Win32/PHP/JS/Android/Python