修复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里面的"要用"代替,下同。博客插入代碼后自動顯示出來了。
這樣出來效果如圖:
可以看到:
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右键菜单背景色和前景色无效问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫网易云音乐最热评论并分析
- 下一篇: sdoi2017苹果树