码迷,mamicode.com
首页 > 其他好文 > 详细

CDialogBuilder 类

时间:2015-04-08 00:50:27      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

说明:我这里去除了压缩文件跟资源文件只考虑_UNICODE宏

1、首先是Create(xml)文件

刚传进来的时候进行判断该字符串是否以‘<‘开头,如果是的话就会默认是xml文件的内容否则则默认是xml文件。所以咱们在给xml文件取名字的时候记得不能以尖括号开头。

a. 当是xml文件的时候:则会调用对应的loadfromfile->loadfrommem:判断该文件的格式是utf8(有无bom)、asci或者是unicode,然后将内容拷贝到LPTSTR m_pstrXML;  然后再调用_Parse()

b.如果是xml文件内容时直接调用_Parse()

 

2、调用CControlUI* CDialogBuilder::Create(IDialogBuilderCallback* pCallback, CPaintManagerUI* pManager, CControlUI* pParent)函数

先将全局的font、image、default、等添加到默认的属性列表。

再将Window的属性列表添加到默认的CPaintMangerUI类中的default 字体,颜色等

最后再调用_Parse(&root, pParent, pManager);即函数

CControlUI* CDialogBuilder::_Parse(CMarkupNode* pRoot, CControlUI* pParent, CPaintManagerUI* pManager)

 

3、关于_Parse三个参数的函数

先根据名字来进行解析该创建哪个控件,如果没找到则进行对应的用户自定义的类型。最后如果是在不行则调用

技术分享
            if( pControl == NULL && m_pCallback != NULL ) {
                pControl = m_pCallback->CreateControl(pstrClass);
            }
View Code

这里的IDialogBuilderCallback* m_pCallback;是在create的时候传进来的接口,里面有对应的createcontrol函数,我们要自己创建对应的子类来实现基类的接口。

比如duilib官方的demo

技术分享
class ComputerExamineUI : public CContainerUI
{
public:
    ComputerExamineUI()
    {
        CDialogBuilder builder;
        CContainerUI* pComputerExamine = static_cast<CContainerUI*>(builder.Create(_T("ComputerExamine.xml"), (UINT)0));
        if( pComputerExamine ) {
            this->Add(pComputerExamine);
        }
        else {
            this->RemoveAll();
            return;
        }
    }
};

class CDialogBuilderCallbackEx : public IDialogBuilderCallback
{
public:
    CControlUI* CreateControl(LPCTSTR pstrClass) 
    {
        if( _tcscmp(pstrClass, _T("ComputerExamine")) == 0 ) return new ComputerExamineUI;
        return NULL;
    }
};
View Code

对应的xml:<ComputerExamine />

 

完事之后

第一步:添加完成之后如果该classname有孩子则递归调用_Parse

第二步:如果有父节点则: pContainer = static_cast<IContainerUI*>(pParent->GetInterface(_T("IContainer")));到这里读者可能会疑惑为什么每个容器控件都有自身的InterfaceName那该如何进行识别?

这里以CHorizontalLayout为例

技术分享
LPVOID CHorizontalLayoutUI::GetInterface(LPCTSTR pstrName)
    {
        if( _tcscmp(pstrName, DUI_CTR_HORIZONTALLAYOUT) == 0 ) return static_cast<CHorizontalLayoutUI*>(this);
        return CContainerUI::GetInterface(pstrName);
    }
View Code

看了这里应该知道了是如何获取到GetInterface的指针了,先在本身查找,如果找不到则向父节点查找。既然本身是容器那肯定会继承CContainerUI,即到了ContainerUI的时候就会正确返回了。

技术分享
    LPVOID CContainerUI::GetInterface(LPCTSTR pstrName)
    {
        if( _tcscmp(pstrName, _T("IContainer")) == 0 ) return static_cast<IContainerUI*>(this);
        else if( _tcscmp(pstrName, DUI_CTR_CONTAINER) == 0 ) return static_cast<CContainerUI*>(this);
        return CControlUI::GetInterface(pstrName);
    }
View Code

第三步:将默认的属性设置到control中,最后将用户设置的属性列表设置到control中。这样子的话如果用户重新定义了属性,则会覆盖对应的默认属性。

这里有一个pControl->SetManger(pManager, null, false); 其实这里是为了在SetAttribute属性的时候调用。

比如:

技术分享
void CControlUI::SetVirtualWnd(LPCTSTR pstrValue)
{
    m_sVirtualWnd = pstrValue;
    m_pManager->UsedVirtualWnd(true);
}
View Code

它这里连判断pManager是否为空的都没有。所以需要调用该函数。然后在后面则进行

if( pManager ) {
pControl->SetManager(NULL, NULL, false);
}

 

 

最后说一下关于CMarkUp 跟 CMarkupNode类

首先我们知道CMarkUp是开源的一个xml解析类,然后该类有一个XMLELEMENT* m_pElements 属性,存储了每个element的相关信息,很有疑问,为什么存储的数据是ULONG iData 跟 ULONG iStart,却不是对应的字符串,这里很容易可以找到的是:

技术分享
LPCTSTR CMarkupNode::GetName() const
{
    if( m_pOwner == NULL ) return NULL;
    return m_pOwner->m_pstrXML + m_pOwner->m_pElements[m_iPos].iStart;
}

LPCTSTR CMarkupNode::GetValue() const
{
    if( m_pOwner == NULL ) return NULL;
    return m_pOwner->m_pstrXML + m_pOwner->m_pElements[m_iPos].iData;
}
View Code

 

直接返回对应的字符串!我们知道这个m_pstrXML是在刚才讲的createmem的函数中进行new的,并将文件里面的内容复制到该属性中。但是又有疑问了,那这个字符串你怎么知道有多长了,那这里就得看里面的解析函数了,在_Parse系列的函数中,当解析到了一个名字之后会在最后一个位置设置‘\0‘作为字符串的结束。

然后该XMLELEMENT存储的方式是以邻接表的方式进行存储的。

<Button name="cxiaoln">

  datas

</Button>

这里的<Button name="cxiaoln">就是istart   datas就是对应的iData  当然了,这里我只是进行简单的说明,它istart进行了‘0‘的分割。成各个name跟对应的值。然后对应的具体属性列表则放在CMarkupNode的_MapAttributes进行相应的解析。

 

CMarkupNode类进行解析对应CMarkup的属性,并将每个element的的name跟value存放在XMLATTRIBUTE m_aAttributes[MAX_XML_ATTRIBUTES]; 

CDialogBuilder 类

标签:

原文地址:http://www.cnblogs.com/cxiaoln/p/4401052.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!