现在的位置: 首页 > 综合 > 正文

dui框架开发系列:XML解析和界面的动态创建

2018年10月16日 ⁄ 综合 ⁄ 共 6439字 ⁄ 字号 评论关闭

大家好,我要介绍的所有知识点都是WINCE/windows触摸屏DUI开源框架constvar(点击下载代码)开发过程中遇到的比较有讨论价值的问题。

 

 本文要讨论的是与界面解析加载相关的XML解析和动态创建界面。

 

XML是directui界面对象配置文件的最好选择,因为它的树形结构很适合描述同样是树形结构的对话框。从XML中可以很清晰的看清界面元素之间的层次关系。同时用XML可以很方便检测语法错误,以及很容易解析。有很多开源的解析XML的代码,这里我们选用的是CMARKUP。 因为它相当于是一个C++类,直接添加到功能就能很简便的使用。

一般的DUI框架会带一些辅助工具来生成这个XML配置,CONSTVAR也是如此。生成和解析的代码原理大致相似。这里的是解析一个对话框的代码。

动态创建对象则可以参考MFC的动态创建对象的实现,或者是搜索该关键词,相关的文章超多就不再累述了。

 

 

         //解析res xml

         CMarkupxml;

         pRes->Parse(xml);

 

         xml.ResetPos();

 

         std::wstringstr;

         std::wstringstrAtt;

         CRuntimeClass*pCls = NULL;

 

         //根据xml创建界面控件

         //第一个结点已存在不需要创建, 默认第一个结点为窗体根结点

         xml.FindNode(CMarkup::MNT_ELEMENT);

 

         //当前父结点

         int                       nRtn = 0;

         VtXmlNode       vtNodesTag;

         IterXmlNode    IterNodesTag, IterPre;

         SXmlNode         xmlNode;

         std::wstring     strClsName;

 

         if(pTribe!= m_pRoot)

         {

                   pTribe->SetHeight(1);// 初始界面高度为

         }

         else

         {

                   pTribe->SetHeight(0);

         }

 

         xmlNode.pNode= pTribe;

         xmlNode.strTag= xml.GetTagName();

         vtNodesTag.push_back(xmlNode);

 

         strAtt= xml.GetAttrib(L"name");

         xmlNode.pNode->SetName(strAtt);

 

 

         xml.ResetPos();

 

         intnRear = 1;

         intnHead = 0;

        

         while(nRear> nHead)

         {

                   IterNodesTag= vtNodesTag.begin() + nHead;

 

                   if(nHead>= 1)

                   {

                            xml.RestorePos(IterNodesTag->strTag.c_str());

                   }

                   else

                   {

                            if(!xml.FindElem(IterNodesTag->strTag.c_str()))

                            {

                                     nHead++;

                                     continue;

                            }

                   }

 

                   xml.IntoElem();

                   while(1)

                   {

                            nRtn= xml.FindNode(CMarkup::MNT_ELEMENT);

                            if(0== nRtn)

                            {

                                     break;

                            }

                            else

                            {

                                     //增加会导致之前的iter失效

                                     IterNodesTag= vtNodesTag.begin() + nHead;

 

                                     xmlNode.strTag= xml.GetTagName();

                                    

                                     //保存位置

                                     xml.SavePos(xmlNode.strTag.c_str());

 

                                     if(xmlNode.strTag.find(L"obj_")== 0)

                                     {

                                               strAtt= xml.GetAttrib(L"type");

 

                                               //创建结点,并设置它的属性

                                               strClsName= strAtt;

                                               pCls= CRuntimeClass::LoadByName(strClsName);

                                               if(NULL!= pCls)

                                               {

// 动态创建对象

                                                        xmlNode.pNode=(CGroup*)pCls->CreateObject();

 

                                                        strAtt= xml.GetAttrib(L"name");

                                                        xmlNode.pNode->SetName(strAtt);

                                                        xmlNode.pNode->SetClassName(strClsName);

 

                                                        //附加属性

                                                        xmlNode.pNode->SetAdditionalAtt(xml);

 

                                                        //添加到父结点

                                                        IterNodesTag->pNode->AddNode(xmlNode.pNode);

                                                        vtNodesTag.push_back(xmlNode);

 

                                                        nRear++;

                                               }

                                     }

                                     elseif(xmlNode.strTag.compare(L"style")==0)

                                     {

                                               strAtt= xml.GetAttrib(L"xyz");

 

                                               intx, y, z, w, h;

                                               swscanf(strAtt.c_str(),L"%d, %d, %d, %d, %d", &x, &y, &w, &h, &z);

                                              

                                               if(pTribe== IterNodesTag->pNode)

                                               {

                                                        //tribe用自己的z

                                                        IterNodesTag->pNode->InitPos(x,y, w, h, IterNodesTag->pNode->GetZ());

                                               }

                                               else

                                               {

                                                        IterNodesTag->pNode->InitPos(x,y, w, h, z);

                                               }

 

                                               BOOLb;

                                               DWORDdw;

                                              

                                               strAtt= xml.GetAttrib(L"visible");

                                               swscanf(strAtt.c_str(),L"%d", &b);

                                               IterNodesTag->pNode->SetVisible(b);

 

                                               strAtt= xml.GetAttrib(L"enable");

                                               swscanf(strAtt.c_str(),L"%d", &b);

                                               IterNodesTag->pNode->SetEnable(b);

 

                                               strAtt= xml.GetAttrib(L"message");

                                               swscanf(strAtt.c_str(),L"%d", &dw);

                                               IterNodesTag->pNode->SetMsg(dw);

 

                                               strAtt= xml.GetAttrib(L"alpha");

                                               swscanf(strAtt.c_str(),L"%d", &b);

                                               IterNodesTag->pNode->SetAlpha(b);

                                               ………….

 

                                               continue;

                                     }

                            }

                   }

 

                   nHead++;

         }

 

         //对象已创建不再重新解析XML

         pTribe->SetCreated(TRUE);

 

 

比较重要的一点是XML只加载了一遍后下次不再创建对象。这种做法的好处是省了解析XML的时间,但缺点也很明显,因为对象没有析构,对象的状态也就会被保持。即每次进入一个界面的时候都要针对性的初始化控件状态。因为运行之后的控件可能状态已经改变。为了达到像加载时的效果就必须手动初始化。

抱歉!评论已关闭.