Duilib 源码分析之 CResourceManager 篇

今天介绍下类 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,这里提供了一种方式,用的上的朋友可以使用下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
duilib是一个开的C++图形界面库,它提供了丰富的控件和布局管理功能,以及良好的跨平台支持。下面我将对duilib码进行简要分析。 1. 基础架构:duilib码采用了模块化的设计,主要分为“Core”和“UI”两个部分。其中,“Core”模块是duilib的核心部分,提供了基础的窗口、消息循环等功能;而“UI”模块则提供了各种控件和布局管理等高级功能。 2. 控件类别:duilib提供了丰富的控件类别,包括基础的窗口类(如窗口、对话框)、容器类(如水平布局、垂直布局)、常用控件类(如按钮、文本框)、自定义控件类等。每个控件类都有相应的成员函数和消息处理函数,以便实现对控件的创建、设置属性和处理事件等操作。 3. 消息处理机制:duilib使用了消息映射的机制来处理控件的事件。每个控件类都有自己的消息映射表,用于将消息和相应的处理函数关联起来。当控件接收到特定的消息时,duilib会根据映射表找到对应的处理函数进行处理。 4. 布局管理:duilib提供了灵活且强大的布局管理功能,可以通过设置布局属性实现控件的自动适应和自动排列。布局管理器可以根据指定的规则对子控件进行自动布局,以适应不同的窗口尺寸。 5. 绘制引擎:duilib使用了自定义的绘制引擎来实现界面绘制。该绘制引擎可以根据控件的属性和状态来决定绘制的方式,以实现不同的视觉效果。 总结来说,duilib分析涉及到基础架构、控件类别、消息处理机制、布局管理和绘制引擎等方面。通过深入研究这些内容,我们可以更好地理解duilib的设计理念和工作原理,以便能够更好地使用和定制duilib提供的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值