失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 修复Duilib MenuDemo右键菜单背景色和前景色无效问题

修复Duilib MenuDemo右键菜单背景色和前景色无效问题

时间:2019-11-17 20:02:30

相关推荐

修复Duilib MenuDemo右键菜单背景色和前景色无效问题

问题描述

1.第三层菜单的选中项的前景色失效。

2.第二层及以上菜单背景色失效。XML中Default设置背景色bkcolor,只有第一层菜单生效,第二层及以后就没有效果了。

复现

直接使用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:

问题分析&解决

既然有源码,那直接找相关源码分析即可,应该问题不大。

解决菜单选中项前景色失效

经过观察可以看出来,第三层菜单的背景其实是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" " />

这样,问题就解决了。

解决菜单背景色失效

同样,在上面的代码中注意到:

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分支的代码,那里没有问题。

END

文章如果有不严谨或者错误的地方,欢迎指正。

如果觉得《修复Duilib MenuDemo右键菜单背景色和前景色无效问题》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。