在开发中突然发现UIScrollBar有一个重大bug,很影响用户体验,现在我把解决方案分享给大家,首先我们看下出BUG的地方
首先打开duilib中的TestApp1_ud.exe实例程序,打开后看最下面有一个CListUI控件,此控件中包含一个垂直的滚动条
这是正常状况下UIScrollBar控件中的滑块外观,颜色为白色
这是鼠标移动到滑块上的外观,滑块颜色为淡蓝色
注意:为了方便演示,方框中的红点标示鼠标的位置
这是鼠标移动到滑块的正下方时滑块的颜色。此时恢复到正常状况下的白色
好了,接下来问题就出现了,当鼠标重新移动到滑块上时,此时滑块颜色重新归为淡蓝色,但是此时将鼠标移动到滑块的左边,也就是移动到CListUI控件内部时,此时滑块颜色依然是淡蓝色
这种的效果很影响用户体验,我们需要的效果是,当我们移动到滑块之外时,需要将滑块颜色变为正常颜色,所以我们只能通过修改系统源码来解决这个问题
首先找到void CScrollBarUI::DoEvent(TEventUI& event)这个函数,此函数在CScrollBarUI.cpp的第638行
然后我们移动到此函数的最下面,找到if( event.Type == UIEVENT_MOUSELEAVE)这行代码
这行代码的意思是当鼠标离开时触发的事件,问题就出在这里了
if( event.Type == UIEVENT_MOUSELEAVE )
{
if( ::PtInRect(&m_rcItem, event.ptMouse ) ) {
if( IsEnabled() ) {
m_uButton1State &= ~UISTATE_HOT;
m_uButton2State &= ~UISTATE_HOT;
m_uThumbState &= ~UISTATE_HOT;
Invalidate();
}
if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this);
}
else {
if (m_pManager) m_pManager->AddMouseLeaveNeeded(this);
return;
}
}
其中PtInRect函数用来判断鼠标是否在滑块范围内,所以我们需要看else中的处理函数,但是,这个函数中没有对滑块状态做任何处理,ok,位置找到了,我们要修改的就是此处代码
else {
if(m_uThumbState & UISTATE_HOT)
{
m_uThumbState &= ~UISTATE_HOT;
Invalidate();
}
if (m_pManager)m_pManager->AddMouseLeaveNeeded(this); return; }
OK,代码比较简单,就不做解释了,此时我们编译运行,效果已经达到了
OK,此处应该鲜花刷起来~haha