[英]MFC: strange behavior when dragging scrollbar thumb
我使用滚动条来显示多行的大块数据(一些背景请参考我之前的问题: MFC: how to reduce the time cost of OnInitialUpdate() for scrolling? )。
滚动功能在以下情况下正常工作:(1)单击箭头按钮,(2)单击滚动轴或(3)滚动鼠标滚轮; 内容正确向上或向下移动。 但是当我拖动滚动拇指时,除非距离非常小,否则它不会真正按预期运行。
当拖得再多一点时,例如向前,它可能会向后跳,有时会一直跳到开头。 鼠标释放时它永远不会停留,而且我从未成功地将拇指一直拖到最后一条记录。
当我仔细观察时,“GetClipBox(...)”似乎没有返回正确的数据。 例如,如果我一直拖到最后,这个函数将返回 rect.top 等于 0。 由于我依靠返回值来计算要绘制的记录集,剩下的就乱七八糟了。
可以在此处访问最小的可重现示例: https : //138.197.210.223/test/My.tar.gz 。 测试时,将拇指一直拖到底,效果更佳。
这是由于WM_VSCROLL 消息的16 位限制。 实际上限制是 32767,而不是文档所说的 65535。 很久以前在一个项目中遇到过同样的问题。
解决方法是修改WM_VSCROLL
消息处理,以便它改用GetScrollInfo()
函数返回的 32 位值。 覆盖OnVScroll()
(转到类视图,选择您的视图并添加WM_VSCROLL
消息处理程序):
void CMyView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// Workaround the 16-bit limitation
if (nSBCode == SB_THUMBPOSITION || nSBCode == SB_THUMBTRACK)
{
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
::GetScrollInfo(m_hWnd, SB_VERT, &si);
// Set nPos to the 32-bit value
nPos = si.nTrackPos;
}
CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}
这应该可以解决问题。
是否添加了WM_HSCROLL或WM_VSCROLL消息?
当窗口的标准水平滚动条中发生滚动事件时,WM_HSCROLL 消息被发送到窗口。 当控件中发生滚动事件时,此消息也会发送给水平滚动条控件的所有者。
当窗口的标准垂直滚动条中发生滚动事件时,WM_VSCROLL 消息被发送到窗口。 当控件中发生滚动事件时,此消息也会发送给垂直滚动条控件的所有者。
我建议您可以尝试将以下代码添加到 OnHScroll 函数或 OnVScroll 函数中:
case SB_THUMBPOSITION:
pScrollBar->SetScrollPos(nPos);
break;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.