您的位置:首页 > 产品设计 > UI/UE

Duilib 源码分析之 CResourceManager 篇

2017-12-14 15:14 671 查看
今天介绍下类 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)
即可,在这个方法中定义文字的
id
value
。 用这种方法加载成功后,会将此值补充到
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_mImageHashMap
m_mXmlHashMap
中,之后,我们平时在创建控件时传入 xml 的地方,和定义控件图片相关属性时,都可以定义为 xml 中的 id。 然后再实际创建控件或者读取图片路径的时候,会首先根据参数从
m_mImageHashMap
m_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
4000
);
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,这里提供了一种方式,用的上的朋友可以使用下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码 开源项目 界面