2016-12-08 10 views
2

EDIT:Как проверить, находится ли полоса прокрутки элемента управления редактирования внизу?

Благодаря @immibis, теперь я могу перейти к нижней части управления успешно используя WM_VSCROLL, но я все еще хочу знать, как вы можете проверить, если полоса прокрутки находится в нижней части.

У меня есть только для чтения управления редактирования:

HWND hMsgDisplay = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY | WS_VSCROLL, 10, 10, 664, 200, hWnd, (HMENU)IDC_MESSAGE_DISPLAY_EDIT, hInst, NULL); 

И я хочу, чтобы перейти к нижней части его. Я пытался это:

SCROLLINFO sb; 
ZeroMemory(&sb, sizeof(sb)); 
sb.cbSize = sizeof(SCROLLBARINFO); 
sb.fMask = SIF_ALL; 
GetScrollInfo(hMsgDisplay, SB_VERT, &sb); 
while (abs(sb.nMax - sb.nPos) > 1) { 
    SendMessage(hMsgDisplay, EM_SCROLL, SB_LINEDOWN, NULL); 
    GetScrollInfo(hMsgDisplay, SB_VERT, &sb); 
} 

Он работал хорошо, когда есть только одна или две строки текста в элементе управления редактирования, но после того, что программа входит в бесконечный цикл и застревает. Я отладил его и выяснил, что даже когда полоса прокрутки серая (она есть, но ее нельзя прокручивать), sb.nMax все равно дает мне ненулевое число, и сколько бы раз я не отправлял сообщение EM_SCROLL, sb.nPos остается 0. Как я могу обнаружить, что полоса прокрутки прокручена вниз?

+0

MSDN говорит отправка EM_SCROLL эквивалентно отправке WM_VSCROLL и WM_VSCROLL имеет опцию SB_BOTTOM. Вы попробовали отправить это вместо этого, чтобы прокрутить вниз до конца? – immibis

+0

В качестве альтернативы используйте [SetScrollPos() '] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb787597.aspx) или [' SetScrollInfo() '] (https: // msdn .microsoft.com/en-us/library/windows/desktop/bb787595.aspx) (поскольку вы уже знаете максимальную позицию из 'GetScrollInfo()'). –

+0

Спасибо за предложение @immibis! Я просто попробовал, и это сработало. Извините, что не просмотрел его сначала, прежде чем публиковать этот вопрос ... Но даже если это разрешено, я все же хочу знать, как вы можете проверить, находится ли полоса прокрутки внизу. – Tyler

ответ

2

для проверки в нижней позиции, используйте этот код

BOOL IsBotomPos(HWND hwnd) 
{ 
    SCROLLINFO si = {sizeof(si), SIF_ALL}; 

    if (GetScrollInfo(hwnd, SB_VERT, &si)) 
    { 
     return si.nPos + si.nPage == (UINT)si.nMax + 1; 
    } 

    return -1; 
} 

так условие si.nPos + si.nPage == (UINT)si.nMax + 1;

это также возвращает true для пустого редактирования или прокрутки еще не активирована (в данном случае nPos == 0 и nPage == nMax + 1)

для прокрутки в нижней части экрана вы можете просто позвонить:

SendMessage(hwnd, EM_SCROLL, SB_BOTTOM, 0);

несмотря на использование SB_BOTTOM с EM_SCROLL недокументированных, он работает в моем тесте

если вы хотите гладкой прокрутки - вы можете использовать следующий код:

void DoSmoothScroll(HWND hwnd, BOOL byPage) 
{ 
    SCROLLINFO si = {sizeof(si), SIF_ALL}; 

    if (GetScrollInfo(hwnd, SB_VERT, &si)) 
    { 
     int n = si.nMax + 1 - si.nPage - si.nPos; 

     if (0 < n) 
     { 
      if (byPage && si.nPage) 
      { 
       n = (n + si.nPage - 1)/si.nPage; 
       LONG r = MAKELONG(si.nPage - 1, TRUE); 
       do 
       { 
        if (SendMessage(hwnd, EM_SCROLL, SB_PAGEDOWN, 0) != r) 
        { 
         break; 
        } 
       } while (--n); 
      } 
      else 
      { 
       do 
       { 
        if (SendMessage(hwnd, EM_SCROLL, SB_LINEDOWN, 0) != MAKELONG(1, TRUE)) 
        { 
         break; 
        } 
       } while (--n); 
      } 
     } 
    } 
} 

ваш можете также комбинировать - первый попробовать быстрый свиток с «недокументированным» SB_BOTTOM, проверьте действительно ли мы прокручиваемся, а если нет - попробуйте гладкую прокрутку

void ScrollEx(HWND hwnd) 
{ 
    SendMessage(hwnd, EM_SCROLL, SB_BOTTOM, 0); 
    DoSmoothScroll(hwnd, TRUE); 
} 

действительно в функции DoSmoothScroll

int n = si.nMax + 1 - si.nPage - si.nPos;

должен быть 0, если SB_BOTTOM работал, и мы просто выйти без дополнительной прокрутки

+0

@Tyler - расширяю код 'DoSmoothScroll' - добавьте опцию select - прокрутите страницу или по строке – RbMm