Duilib使用的点滴记录

       最近在一个新的产品上使用了duilib,终于可以方便的做出漂亮的界面了,在此要感谢开发者。不过在使用的过程中也发现了几个问题,但duilib的源码好像已经不更新了,所以就在此记录下来,方便后来人。

       遇到的问题主要TreeView这个控件,一个是树节点模板加载的问题,一个是树的叶子节点不显示展开按钮的问题。

       1. 树节点模板加载

     在我们的实际使用中,一般只是在主xml中写一个TreeView,然后TreeNode会写在一个单独的xml中,比如就叫treenode.xml,然后通过这个treenode.xml来动态生成TreeNode节点,再添加到TreeView下面。但我在实际使用中发现无法生成TreeNode,老是崩溃。后来通过跟踪代码发现问题处在CDialogBuilder::_Parse()这个函数中,具体在275行处,代码如下:

        //树控件XML解析
        else if( _tcscmp(pstrClass, _T("TreeNode")) == 0 ) {
            CTreeNodeUI* pParentNode    = static_cast<CTreeNodeUI*>(pParent->GetInterface(_T("TreeNode")));
            CTreeNodeUI* pNode            = new CTreeNodeUI();
            if(pParentNode){
                if(!pParentNode->Add(pNode)){
                    delete pNode;
                    continue;
                }
            } 

           //...

          continue;

        }

        那么问题就出在

        CTreeNodeUI* pParentNode    = static_cast<CTreeNodeUI*>(pParent->GetInterface(_T("TreeNode")));

       这一句,在使用pParent的时候,没有先判断是否为NULL,对于TreeView和TreeNode在一个xml文件中的,自然是没有问题的,因为pParent不会为NULL,但对于我从treenode.xml创建的来说,就有问题了,这个时候pParent会为NULL,所以要先判断下。

        改了这里就可以了么?显然不是。改好后,你会发现返回的总是NULL,再看下代码,你会发现没有把创建的pNode赋值给pReturn,从而导致总是返回NULL。所以,在continue之前要把pNode赋值给pReturn。

       2. 叶子节点展开按钮

       下面再来说说叶子节点的问题。加入选择了显示展开按钮,那么对于所有的树节点都是会显示的。但其实对于没有子节点的叶子节点来说,不应该显示这个按钮才对。最开始,我以为可以通过设置TreeNode的SetVisibleFolderBtn()函数来取消显示,但发现不行。原来是在重绘的时候,会先判断该按钮是否可见,如果不可见,就不重绘了。所以问题就出现了,我们是从可见转换到不可见,应该重绘才对。

        既然从可见设置到不可见不行,我就想反操作一下,先让所有的展开按钮不可见,然后非叶子节点都设置展开按钮可见就可以了。经过实践,发现的确可以实现。不过叶子节点的位置不太好看,有点太靠前了。我想要的效果是展开按钮的空间位置依然存在,只是是空的而已。

        因为不想改动duilib的代码,所以我只好改动我的代码(方式搓了点)。对于叶子节点,取到展开按钮后,强制把它的几个关联图片全都设置成空。最后终于达到我要的效果,唯一的遗憾是点击叶子几点的展开按钮位置,还是可以发现有不同的,没有实现完全空着的感觉。


你可能感兴趣的:(duilib)