MF C: странное поведение при перетаскивании полосы прокрутки большим пальцем - PullRequest
2 голосов
/ 18 марта 2020

Я использую полосу прокрутки, чтобы показать большой фрагмент данных со многими строками (для некоторого фона, пожалуйста, обратитесь к моему предыдущему вопросу: MF C: как уменьшить временные затраты на OnInitialUpdate () для прокрутки? ).

Функция прокрутки работает нормально, когда: (1) нажатие на кнопку со стрелкой, (2) нажатие на вал прокрутки или (3) вращение колесика мыши; содержимое перемещается вверх или вниз правильно. Но когда я перетаскиваю большой палец прокрутки, он на самом деле ведет себя не так, как ожидалось, за исключением очень маленького расстояния.

При перетаскивании немного больше, например, вперед, он может отскочить назад, а иногда и полностью к началу. Он никогда не остается, когда мышь отпущена, и я никогда не могу успешно перетащить большой палец до последней записи.

При более тщательном рассмотрении «GetClipBox (...)», кажется, не возвращает правильные данные. Например, если я перетащу весь путь до конца, эта функция вернет rect.top равным нулю. Поскольку я полагаюсь на возвращаемое значение для расчета набора записей для рисования, все остальное запутано.

Здесь можно найти минимальный воспроизводимый пример: https://138.197.210.223/test/My.tar.gz. При тестировании перетащите большой палец до конца для лучшего эффекта.

Ответы [ 2 ]

2 голосов
/ 20 марта 2020

Это связано с 16-битным пределом сообщения WM_VSCROLL . На самом деле ограничение составляет 32767, а не 65535, как говорится в документации. Если у проекта та же проблема в течение долгого времени, то go.

Обходной путь - изменить обработку сообщения WM_VSCROLL так, чтобы вместо него использовалось 32-битное значение, возвращаемое функцией GetScrollInfo(). Переопределите OnVScroll() (go в представлении классов, выберите представление и добавьте обработчик сообщений 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);
}

Это должно решить проблему.

0 голосов
/ 18 марта 2020

Добавили ли вы сообщение WM_HSCROLL или WM_VSCROLL ?

Сообщение WM_HSCROLL отправляется окну, когда в стандарте окна происходит событие прокрутки горизонтальная полоса прокрутки. Это сообщение также отправляется владельцу горизонтальной полосы прокрутки, когда в элементе управления происходит событие прокрутки.

Сообщение WM_VSCROLL отправляется окну, когда событие прокрутки происходит в стандартной вертикальной полосе прокрутки окна. Это сообщение также отправляется владельцу элемента управления вертикальной полосы прокрутки, когда в элементе управления происходит событие прокрутки.

Я предлагаю вам попробовать добавить следующий код в функцию OnHScroll или функцию OnVScroll:

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