简体   繁体   English

MFC:拖动滚动条拇指时的奇怪行为

[英]MFC: strange behavior when dragging scrollbar thumb

I use scrollbar to show a large piece of data with many lines (for some background please refer to my previous question: MFC: how to reduce the time cost of OnInitialUpdate() for scrolling? ).我使用滚动条来显示多行的大块数据(一些背景请参考我之前的问题: MFC: how to reduce the time cost of OnInitialUpdate() for scrolling? )。

The scrolling function works fine when: (1) clicking on arrow button, (2) clicking on scroll shaft or (3) rolling the mouse wheel;滚动功能在以下情况下正常工作:(1)单击箭头按钮,(2)单击滚动轴或(3)滚动鼠标滚轮; the content moves upwards or downwards correctly.内容正确向上或向下移动。 But when I drag the scroll thumb, it doesn't really behave as expected unless very tiny distance.但是当我拖动滚动拇指时,除非距离非常小,否则它不会真正按预期运行。

When dragging a little bit more, eg forward, it could jump back and sometimes all the way to the beginning.当拖得再多一点时,例如向前,它可能会向后跳,有时会一直跳到开头。 It never stays when mouse released, and I never successfully drag the thumb all the way to the last record.鼠标释放时它永远不会停留,而且我从未成功地将拇指一直拖到最后一条记录。

As I take closer look, "GetClipBox(...)" seems not return correct data.当我仔细观察时,“GetClipBox(...)”似乎没有返回正确的数据。 For example, if I drag all the way to the end, this function would return rect.top equals to zero.例如,如果我一直拖到最后,这个函数将返回 rect.top 等于 0。 Since I rely on the return value to calculate the set of records to draw, the rest is messed up.由于我依靠返回值来计算要绘制的记录集,剩下的就乱七八糟了。

A minimal reproducible example can be accessed here: https://138.197.210.223/test/My.tar.gz .可以在此处访问最小的可重现示例: https : //138.197.210.223/test/My.tar.gz When testing, drag thumb all the way to the end for better effect.测试时,将拇指一直拖到底,效果更佳。

This is due to the 16-bit limit of the WM_VSCROLL message .这是由于WM_VSCROLL 消息16 位限制 Actually the limit is 32767, not 65535 as the documentation says.实际上限制是 32767,而不是文档所说的 65535。 Had the same problem in a project a loooong time ago.很久以前在一个项目中遇到过同样的问题。

The workaround is to modify the WM_VSCROLL message processing so that it uses the 32-bit value returned by the GetScrollInfo() function instead.解决方法是修改WM_VSCROLL消息处理,以便它改用GetScrollInfo()函数返回的 32 位值。 Override OnVScroll() (go to Class View, select your view and add the WM_VSCROLL message handler):覆盖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);
}

This should fix the problem.这应该可以解决问题。

Whether you have added WM_HSCROLL or WM_VSCROLL message?是否添加了WM_HSCROLLWM_VSCROLL消息?

The WM_HSCROLL message is sent to a window when a scroll event occurs in the window's standard horizontal scroll bar.当窗口的标准水平滚动条中发生滚动事件时,WM_HSCROLL 消息被发送到窗口。 This message is also sent to the owner of a horizontal scroll bar control when a scroll event occurs in the control.当控件中发生滚动事件时,此消息也会发送给水平滚动条控件的所有者。

The WM_VSCROLL message is sent to a window when a scroll event occurs in the window's standard vertical scroll bar.当窗口的标准垂直滚动条中发生滚动事件时,WM_VSCROLL 消息被发送到窗口。 This message is also sent to the owner of a vertical scroll bar control when a scroll event occurs in the control.当控件中发生滚动事件时,此消息也会发送给垂直滚动条控件的所有者。

I suggest you could try to add the following code to the OnHScroll function or OnVScroll function:我建议您可以尝试将以下代码添加到 OnHScroll 函数或 OnVScroll 函数中:

case SB_THUMBPOSITION:
    pScrollBar->SetScrollPos(nPos);
    break;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM