wangchyz / duilib_googlecode

从google code备份过来,仅作存档
https://github.com/duilib/duilib
8 stars 10 forks source link

UIDesigner Code Bug 2011-11-15 #17

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
MultiUITracker.cpp文件中的ExcludeChildren函数实现有问题

以下是原来的代码:
    for(int i=0; i<arrSelected.GetSize()-1; i++)
    {
        CControlUI* pControl1 = arrSelected[i];
        for(int j=i+1; j<arrSelected.GetSize(); j++)
        {
            if(pDepth[i] == pDepth[j]) continue;
            CControlUI* pControl2 = arrSelected[j];
            if(pDepth[i] < pDepth[j])
            {
                int depth = pDepth[j] - pDepth[i];
                while(depth-- && pControl2)
                    pControl2 = pControl2->GetParent();
                if(pControl1 == pControl2)
                    arrSelected.RemoveAt(j--);
            }
            else
            {
                int depth = pDepth[i] - pDepth[j];
                while(depth-- && pControl1)
                    pControl1 = pControl1->GetParent();
                if(pControl1 == pControl2)
                    arrSelected.RemoveAt(i--);          // 问题1:这里的i已经被remove,后面pControl1已经无效
            }
        }
    }

问题2:循环里面用到pDepth,同时循环里会删除arrSelected里面的元
素,因此一旦有删除的时候,pDepth实际已经不再有效。比如说i 
= 0,j = 1时,删除了j = 1;则循环的下一次比较i = 0,j = 
1;这里的arrSelected[1]实际是原来的arrSelected[2];但是pDepth[1]还是�
��来的arrSelected[1]的深度。

发一段修改后的代码,仅供参考

    int size = arrSelected.GetSize();
    int* pDepth = new int[size];
    for(int i=0; i<size; i++)
    {
        ExtendedAttributes* pExtended = (ExtendedAttributes*)arrSelected[i]->GetTag();
        pDepth[i] = pExtended->nDepth;
    }

    bool* pRemoveable = new bool[size];
    memset(pRemoveable,0,sizeof(bool)*size);

    for(int i=0; i<arrSelected.GetSize()-1; i++)
    {
        if(pRemoveable[i]) continue;
        CControlUI* pControl1 = arrSelected[i];
        for(int j=i+1; j<arrSelected.GetSize(); j++)
        {
            if(pRemoveable[j]) continue;
            if(pDepth[i] == pDepth[j]) continue;
            CControlUI* pControl2 = arrSelected[j];
            if(pDepth[i] < pDepth[j])
            {
                int depth = pDepth[j] - pDepth[i];
                while(depth-- && pControl2)
                    pControl2 = pControl2->GetParent();
                if(pControl1 == pControl2) pRemoveable[j] = true;
            }
            else
            {
                int depth = pDepth[i] - pDepth[j];
                while(depth-- && pControl1)
                    pControl1 = pControl1->GetParent();
                if(pControl1 == pControl2)
                {
                    pRemoveable[i] = true;
                    break;
                }
            }
        }
    }

    int removecount = 0;
    for(int i = 0;i < size;++i)
    {
        if(!pRemoveable[i]) continue;
        ASSERT(i >= removecount);
        arrSelected.RemoveAt(i-removecount);
        ++removecount;
    }

    delete[] pDepth;delete[] pRemoveable;

Original issue reported on code.google.com by zentr...@126.com on 15 Nov 2011 at 7:03