完善Duilib自带的MenuDemo中的小问题

直接使用MenuDemo的代码,改了一下XML布局,其中Default设置如下:

<Default name="Menu" value="inset="2,2,2,2" bkcolor="#ff43CD80" itemtextpadding="30,0,0,0" itemselectedbkcolor="#FF0179ff" itemhottextcolor="#FFFFFFFF" " />  

(注意,xml中value里面的"要用&quot;代替,下同。博客插入代码后自动显示出来了。)

这样出来效果如图:

看到有两个小问题:

1.第三层菜单的选中效果和前两个不一样。

2.XML中Default设置绿色背景bkcolor="#ff43CD80";但是只有第一层菜单是绿色的,后面就没有效果了。

以为是自己修改导致失效,回头看了原版的Demo,发现也有这个问题。原版Demo:

瞎几把分析&解决过程:

1.对于第一个问题,可以看出来第三层菜单的背景其实是List(Menu控件继承自List)控件的默认背景。那我们就找它为什么创建的时候会用默认的属性。人工仔细查找一番,终于在UIMenu.cpp中看到如下代码:

//UIMenu.cpp  
  
// MenuUI  
const TCHAR* const kMenuUIClassName = _T("MenuUI");  
const TCHAR* const kMenuUIInterfaceName = _T("Menu");  
  
LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
    if( uMsg == WM_CREATE ) {  
        if( m_pOwner != NULL) {  
              
            //...  
              
            LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(kMenuUIInterfaceName);  
            if (pDefaultAttributes) {  
                m_pLayout->SetAttributeList(pDefaultAttributes);  
            }  
            m_pLayout->SetBkColor(0xFFFFFFFF);  
            m_pLayout->SetBorderColor(0xFF85E4FF);  
            m_pLayout->SetBorderSize(0);  
            m_pLayout->SetAutoDestroy(false);  
            m_pLayout->EnableScrollBar();  
              
            //...  
              
        }else{  
            //...  
        }  
    }  
    //...  
}  

看到pDefaultAttributes变量就是关键所在,右键查看GetDefaultAttributeList()的定义:

//UIManager.cpp  
LPCTSTR CPaintManagerUI::GetDefaultAttributeList(LPCTSTR pStrControlName) const  
{  
    CDuiString* pDefaultAttr = static_cast<CDuiString*>(m_ResInfo.m_AttrHash.Find(pStrControlName));  
    if( !pDefaultAttr ) pDefaultAttr = static_cast<CDuiString*>(m_SharedResInfo.m_AttrHash.Find(pStrControlName));  
    if (pDefaultAttr) return pDefaultAttr->GetData();  
    return NULL;  
}  

GetDefaultAttributeList(kMenuUIInterfaceName);  

传入的是自定义的Menu控件名称,Duilib不自带,所以:

pDefaultAttr = static_cast<CDuiString*>(m_ResInfo.m_AttrHash.Find(pStrControlName));

返回空值。接下来就是这个了:

pDefaultAttr = static_cast<CDuiString*>(m_SharedResInfo.m_AttrHash.Find(pStrControlName)); 

可以看到找的是带Shared属性的。恍然大悟,回头看看布局XML:

Default name="Menu" value="inset="2,2,2,2" bkcolor="#ff43CD80" itemtextpadding="30,0,0,0" itemselectedbkcolor="#FF0179ff" itemhottextcolor="#FFFFFFFF" " />  

发现没有shared属性,于是加上:

<Default name="Menu" shared="true" value="inset="2,2,2,2" bkcolor="#ff43CD80" itemtextpadding="30,0,0,0" itemselectedbkcolor="#FF0179ff" itemhottextcolor="#FFFFFFFF" " />  

问题解决。

2.第二个问题,在上面的代码中注意到:

LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(kMenuUIInterfaceName);  
if (pDefaultAttributes) {  
 m_pLayout->SetAttributeList(pDefaultAttributes);  
}  
m_pLayout->SetBkColor(0xFFFFFFFF);  
m_pLayout->SetBorderColor(0xFF85E4FF);  
m_pLayout->SetBorderSize(0);  
m_pLayout->SetAutoDestroy(false);  
m_pLayout->EnableScrollBar();  

这个顺序是有点问题的,至于为什么加载了默认属性后还要设置一遍,应该是在暗示可以通过代码在这个地方修改属性。改过来就行:

//UIMenu.cpp  
LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
    if( uMsg == WM_CREATE ) {  
        if( m_pOwner != NULL) {  
              
            //...  
              
            m_pLayout->SetBkColor(0xFFFFFFFF);  
            m_pLayout->SetBorderColor(0xFF85E4FF);  
            m_pLayout->SetBorderSize(0);  
            m_pLayout->SetAutoDestroy(false);  
            m_pLayout->EnableScrollBar();  
              
            LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(kMenuUIInterfaceName);  
            if (pDefaultAttributes) {  
                m_pLayout->SetAttributeList(pDefaultAttributes);  
            }  
              
            //...  
              
        }else{  
            //...  
        }  
    }  
    //...  
}  

那为什么第一层菜单背景没有问题呢?

因为第一层菜单的 m_pOwner = NULL,走的是else分支的代码,那里没有问题。

最后效果:

新手写博客,记录一些自己解决的一些小问题。可能有不严谨或者错误的地方,请读者谅解。同时,如果哪里有错误,欢迎指出以便改正。

阅读更多
文章标签: Duilib MenuDemo 菜单
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭