我正在使用this logging listbox,这恰好是一个所有者绘制的列表框。我注意到,当一次滚动多行时,例如使用鼠标滚轮或单击滚动条,它会以一种奇怪的方式进行。
通常情况下,当您使用滚轮滚动时,您可以看到整个列表顺利上升,例如3行,以及3个来自底部的新行。我在这个控件中看到的就好像一个新的页面,从下面开始的3行,从顶部开始,这对用户来说非常混乱。
我也尝试了this other listbox并且它显示了相同的行为,因此它似乎与所有者有关。
有关如何解决此问题的任何想法?
答案 0 :(得分:2)
我不知道为什么你被投票了。这是一个真正的问题。这就是我所做的修复它。我已经创建了自己的CListBox派生类。在那里,我为WM_TIMER和WM_MOUSEWHEEL事件创建了处理程序。
在鼠标滚轮的处理程序中,我指定了这个:
#define TIMER_SCROLLING 8
BOOL CMyListBox::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
//return CListBox::OnMouseWheel(nFlags, zDelta, pt);
// It turns out that a Listbox control created with the LBS_OWNERDRAWVARIABLE style does not
// handle the mouse wheel correctly. The scroll effect is very jumpy; so bad in fact, that if
// you want to use that style, it is advisable to intercept WM_MOUSEWHEEL to either disable it
// or write your own handler.
// 'return TRUE' disables the scroll effect
#if 0
// This will scroll one item at a time.
// uncomment these lines if this is what you are after
if(zDelta > 0)
{
SetTopIndex(GetTopIndex()-1);
}
else
{
SetTopIndex(GetTopIndex()+1);
}
return TRUE;
#endif
// Will use timer to scroll the items smoothly.
// The scrolling is done in OnTimer event
KillTimer(TIMER_SCROLLING);
const int SCROLL_DELTA = 3;
if(zDelta > 0)
{
// scrolling up
m_nStep -= SCROLL_DELTA;
}
else
{
// scrolling down
m_nStep += SCROLL_DELTA;
}
SetTimer(TIMER_SCROLLING, 20, NULL);
return TRUE;
}
这就是我在WM_TIMER处理程序中编码的内容:
void CMyListBox::OnTimer(UINT_PTR nIDEvent)
{
if(nIDEvent == TIMER_SCROLLING)
{
if(m_nStep < 0)
{
// scrolling up
int nPos = GetTopIndex();
if(nPos == 0)
{
m_nStep = 0;
KillTimer(TIMER_SCROLLING);
}
else
{
SetTopIndex(nPos-1);
m_nStep++;
}
}
else if(m_nStep > 0)
{
// scrolling down
int nPos = GetTopIndex();
if(nPos == GetCount()-1)
{
m_nStep = 0;
KillTimer(TIMER_SCROLLING);
}
else
{
SetTopIndex(nPos+1);
m_nStep--;
}
}
else
KillTimer(TIMER_SCROLLING);
}
else
CListBox::OnTimer(nIDEvent);
}
希望,这将有助于您和其他人。我可能需要考虑将它放在Codeproject
上更新:m_nStep
被定义为CMyListBox类的私有int
成员。在类构造函数中初始化为零;