最新消息:想得多,做的少。一天到晚瞎鸡巴搞。

duilib源码剖析 day4 属性和控件是如何组装存储的

曲径通幽 阿虚 120浏览 0评论

属性的解析和存储

.      解析属性的逻辑是在CDialogBuilder:: Create()的for中。解析方式没有自行脑补的那么高深,完全就是通过字符串判断来做解析的。通过字符串比较出设置的属性和值然后调用API函数进行设置。

.     属性解析全部都是存储在CPaintManagerUI::m_SharedResInfo中。m_SharedResInfo是一个结构体对象。Image:m_ImageHash、Font:m_CustomFonts、Default:m_AttrHash、MultiLanguage:m_MultiLanguageHash。

//资源类型
typedef struct DUILIB_API tagTResInfo
{
    //默认禁用颜色
	DWORD m_dwDefaultDisabledColor;
    //默认字体颜色
	DWORD m_dwDefaultFontColor;
    //超链接字体颜色
	DWORD m_dwDefaultLinkFontColor;
    //超链接鼠标悬停字体颜色
	DWORD m_dwDefaultLinkHoverFontColor;
    //默认选择背景颜色
	DWORD m_dwDefaultSelectedBkColor;
	//当前使用的默认字体
    TFontInfo m_DefaultFontInfo;
    //自定义字体
	CDuiStringPtrMap m_CustomFonts;
    //图片资源存储
	CDuiStringPtrMap m_ImageHash;
    //默认属性列表
	CDuiStringPtrMap m_AttrHash;
    //多语言
	CDuiStringPtrMap m_MultiLanguageHash;
} TResInfo;

.     不过上面也可能存储在TResInfo m_ResInfo;中。bool变量控制存储在不同的成员属性中。存储在共享资源或者是非共享资源是通过每个属性的add函数最后一个参数bShared和CPaintManagerUI::m_bForceUseSharedRes两者一个为真将存储在m_SharedResInfo否则CPaintManagerUI::m_ResInfo。

Window属性

.     window属性设置解析在专门的CPaintManagerUI::SetWindowAttribute()中。duilbi对window属性提供如下设置:size、sizebox、caption、roundcorner、mininfo、maxinfo、showdirty、noactivate、opacity、layeredopacity、layeredimage、disabledfontcolor、defaultfontcolor、linkfontcolor、linkhoverfontcolor、selectedcolor。偶尔几个属性也存储在CPaintManagerUI::m_bForceUseSharedRes或者CPaintManagerUI::m_ResInfo中。大部分写在成员变量中(size:m_szInitWindowSize; sizebox:m_rcSizeBox;caption:m_rcCaption;roundcorner:m_szRoundCorner;mininfo:m_szMinWindow;maxinfo:m_szMaxWindow;showdirty:m_bShowUpdateRect;noactivate:m_bNoActivate;opacity:m_nOpacity;layeredopacity:m_nOpacity;m_bLayeredChanged;layeredimage:TDrawInfo m_diLayered.sDrawString;)。

控件是如何组装存储的

.     在CDialogBuilder::_Parse()中,还是通过循环的方式遍历的XML来组织控件。循环内部通过递归_Parse()来检索每项XML子节点控件。

if( node.HasChildren() ) 
{
    //解析控件中的子控件
    _Parse(&node, pControl, pManager);
}

.     遍历到深处没有子节点时通过获取父控件的容器指针IContainerUI*将子控件new出来的控件指针存储在IContainerUI:: m_items中。

//如果当前容器为NULL就获取父控件的容器
if( pContainer == NULL ) 
    pContainer = static_cast<IContainerUI*>(pParent->GetInterface(DUI_CTR_ICONTAINER));
if( pContainer == NULL ) 
    return NULL;
//将当前控件添加到父控件容器中。
if( !pContainer->Add(pControl) ) 
{
    pControl->Delete();
    continue;
}

.     对于控件的属性,先搜索并设置Define标签给定的默认属性。

// Init default attributes
if( pManager ) 
{
    //如果有pManager那么就尝试通过控件名称来获取pManager中存储的默认属性列表。
    pControl->SetManager(pManager, NULL, false);
    LPCTSTR pDefaultAttributes = pManager->GetDefaultAttributeList(pstrClass);
    if( pDefaultAttributes ) 
    {
        //有默认属性列表那么就设置默认属性
        pControl->SetAttributeList(pDefaultAttributes);
    }
}

.     设置默认属性后再设置用户自己配置的属性列表。

// Process attributes
if( node.HasAttributes() ) 
{
    //如果有属性那么就设置用户设置的一些属性
    // Set ordinary attributes
    int nAttributes = node.GetAttributeCount();
    for( int i = 0; i < nAttributes; i++ ) 
    {
        pControl->SetAttribute(
            node.GetAttributeName(i), 
            node.GetAttributeValue(i));
    }
}

.     通过duilib提供的简略文档和整理现有的Duilib控件类可以确定都是继承CControlUI类。

转载请注明:虚无 » duilib源码剖析 day4 属性和控件是如何组装存储的

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址