Duilib 源码分析之 CResourceManager 篇

来源:互联网 发布:淘宝神笔卖家推荐 编辑:程序博客网 时间:2024/05/22 14:34

今天介绍下类 CResourceManager , 本帖基于的 Duilib 版本为 “Duilib 开源项目圈2群” 中下载的版本,有些版本可以没有这部分代码。
这个类主要分为两大作用:

加载控件的文字, 具体的实现方式也有两种

  • 在 xml 中定义界面文字,像如下代码:

        <?xml version="1.0" encoding="utf-8"?>    <Res>      <Text id="lantext" value="切换到英文" />    </Res>

    之后通过调用 BOOL LoadLanguage(LPCTSTR pstrXml) 将 xml 中定义的文字加载到成员 m_mTextResourceHashMap 中。在实际想使用事先定义好的文字时,需要先为控件属性添加 resourcetext="true", 且控件的 text 需定义为 xml 的某个 id 参考如下代码:

    CDuiString CControlUI::GetText() const{    if (!IsResourceText()) return m_sText;    return CResourceManager::GetInstance()->GetText(m_sText);}

    只有在设置了此属性后才会从 CResourceManager 中加载文字。

  • 第二种方式是从代码中动态加载文字,这种方式是在上述方法未读取到文字的情况下才进行, 也就是说已经定义了 resourcetext="true" , 但是控件的 text 属性的值却未在 xml 定义过。 此时会调用如下代码:

    CDuiString CResourceManager::GetText(LPCTSTR lpstrId, LPCTSTR lpstrType){    if(lpstrId == NULL) return _T("");    CDuiString *lpstrFind = static_cast<CDuiString *>(m_mTextResourceHashMap.Find(lpstrId));    if (lpstrFind == NULL && m_pQuerypInterface)    {        lpstrFind = new CDuiString(m_pQuerypInterface->QueryControlText(lpstrId, lpstrType));        m_mTextResourceHashMap.Insert(lpstrId, (LPVOID)lpstrFind);    }    return lpstrFind == NULL ? lpstrId : *lpstrFind;}

    上述代码第 5 行,在从 xml 中读取失败的情况下,会调用 m_pQuerypInterface->QueryControlText(lpstrId, lpstrType) 读取文字。 我们可以让某个类继承自 IQueryControlText 实例化方法 LPCTSTR QueryControlText(LPCTSTR lpstrId, LPCTSTR lpstrType) 即可,在这个方法中定义文字的 idvalue。 用这种方法加载成功后,会将此值补充到 m_mTextResourceHashMap

加载控件的图片或者加载界面所需 xml

xml 定义如下所示

<?xml version="1.0" encoding="utf-8"?><Res>  <Image id="sysbtn_menu_normal" path="sysbtn/btn_menu_normal.png" />  <Image id="sysbtn_menu_hot" path="sysbtn/btn_menu_highlight.png" />  <Image id="sysbtn_menu_pushed" path="sysbtn/btn_menu_down.png" />  <Xml id="XML_MAIN" path="main.xml"/>  <Xml id="XML_MSG" path="msg.xml"/></Res>

然后通过调用 BOOL LoadResource(STRINGorID xml, LPCTSTR type = NULL) 将此 xml 加载到 m_mImageHashMapm_mXmlHashMap 中,之后,我们平时在创建控件时传入 xml 的地方,和定义控件图片相关属性时,都可以定义为 xml 中的 id。 然后再实际创建控件或者读取图片路径的时候,会首先根据参数从 m_mImageHashMapm_mXmlHashMap 中读取,未读取到的情况下,直接读取传入的参数,参考如下代码:

CControlUI* CDialogBuilder::Create(STRINGorID xml, LPCTSTR type, IDialogBuilderCallback* pCallback,         CPaintManagerUI* pManager, CControlUI* pParent)    {        //资源ID为0-65535,两个字节;字符串指针为4个字节        //字符串以<开头认为是XML字符串,否则认为是XML文件        if(HIWORD(xml.m_lpstr) != NULL && *(xml.m_lpstr) != _T('<')) {            LPCTSTR xmlpath = CResourceManager::GetInstance()->GetXmlPath(xml.m_lpstr);            if (xmlpath != NULL) {                xml = xmlpath;            }        }        ......    }

上段代码第 7 行,首先从 CResourceManager 加载 xml。然后是加载图片的代码:

TImageInfo* CRenderEngine::LoadImage(LPCTSTR pStrImage, LPCTSTR type, DWORD mask, HINSTANCE instance)    {           if(pStrImage == NULL) return NULL;        CDuiString sStrPath = pStrImage;        if( type == NULL )  {            sStrPath = CResourceManager::GetInstance()->GetImagePath(pStrImage);            if (sStrPath.IsEmpty()) sStrPath = pStrImage;            else {                /*if (CResourceManager::GetInstance()->GetScale() != 100) {                    CDuiString sScale;                    sScale.Format(_T("@%d."), CResourceManager::GetInstance()->GetScale());                    sStrPath.Replace(_T("."), sScale);                }*/            }        }        return LoadImage(STRINGorID(sStrPath.GetData()), type, mask, instance);    }

上段代码第 7 行,首先从 CResourceManager 中加载。

这个类到此介绍完了,是一个工具类,实际使用过程中,我们可能会采取各种方法来加载文字,或者图片xml,这里提供了一种方式,用的上的朋友可以使用下。