Как изменить размер бегунка у скролла

Тема в разделе "WASM.WIN32", создана пользователем provocateur, 16 сен 2008.

  1. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    всем известно, что в какой-то момент размер бегунка у скролла становится очень маленьким и "поймать" становится очень сложно.
    Возможно кто-то занимался этим вопросом и решил проблему?

    Отдельно создавать и обрабатывать скролл не хочется. Очень желательно пользоваться тем что уже есть в контролах listbox, edit и т.п.

    Код (Text):
    1. hList = CreateWindowEx (WS_EX_STATICEDGE,
    2. "Listbox",
    3. NULL,
    4. WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_NOINTEGRALHEIGHT,
    5. 0, 0, 100, 100, hwnd, (HMENU)ID_LIST, hInstance, NULL);
    вот от этого и хочется плясать.
    перерыл кучу информации, такое довольно просто возможно в .NET, но нужно на win32api
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    SetScrollInfo в SCROLLINFO задать nPage = 0 и бегунок будет стандартно-фиксированного размера
    работает с любыми окнами имеющими полосы прокрутки.
     
  3. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    сделал вот так:
    Код (Text):
    1. SCROLLINFO lpsi;
    2.     lpsi.cbSize = sizeof(lpsi);
    3.     lpsi.fMask = SIF_PAGE;
    4.     lpsi.nPage = 0;
    5.     SetScrollInfo  ( hList, SB_VERT, &lpsi, TRUE );
    не помогает
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Да с "не своими" окнами этот способ работает кривовато.
    как вариант после любых изменений (добавление удаление строк, ресайзинг и т.п.) делать
    Код (Text):
    1.      mov [ScrInf.cbSize], sizeof ScrInf
    2.      mov [ScrInf.fMask], SIF_PAGE or SIF_RANGE
    3.      invoke GetScrollInfo, [hList], SB_VERT, addr ScrInf
    4.      mov eax, [ScrInf.nPage]
    5.      sub [ScrInf.nMax], eax
    6.      mov [ScrInf.nPage], 0
    7.      invoke SetScrollInfo, [hList], SB_VERT, addr ScrInf, TRUE
    хотя конечно не самый изящный способ.
     
  5. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    эх.
    делает конечно, но такая фигня получается :)
    размер меняется, но пользоваться им уже невозможно
     
  6. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Или субклассировать Listbox и делать это в перехватчике WM_VSCROLL возможно использование станет удобоваримее ;)
     
  7. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    такая мысля у меня тоже была, но мозгоф не хватает.
    хватило только на:

    Код (Text):
    1. LRESULT FAR PASCAL ListboxSubClassFunc ( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    2. {
    3.  
    4.  
    5.     switch ( message )
    6.     {
    7.  
    8.     }
    9.    return CallWindowProc ( lpfnListboxOldWndProc, hWnd, message, wParam, lParam);
    10. }
    т.е. нужно добавить "case WM_VSCROLL:" ? или уже всякие WM_PAINT ? но инфы по отображению скролла нету.

    в описании WM_VSCROLL написано:

    а вот размера для scroll box нету, как его найти?

    видно придется пока оставить как есть
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Перехватываешь только то что нужно, остальное просто пересылаешь родной функции Listbox, пусть сама разбирается ;)
    через GetScrollInfo\SetScrollInfo (#4) (в своём окне со встроенными прокрутками так и делал нормально работало) и свою обработку WM_VSCROLL имхо лучше делать не до а после того как Listbox его обработает.
     
  9. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    Y_Mur, и совсем уж неприличный вопрос: как делать свою обработку после стандартной?
     
  10. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    сначала CallWindowProc(...), запоминаешь результат во временной переменной, затем case WM_VSCROLL, код из #4 и напоследок return с запомненным кодом возвращённым штатной lpfnListboxOldWndProc ;)
     
  11. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    блин, оказывается первый раз, я getscrollinfo не сделал, у меня там два раза set...
    щас сделал, стало лучше намного, правда под конец списка, имеется накоторое недопонимание :) и непонятно, в какой-то еще момент размер меняется, надо еще сообщения ловить.
    а вот с сабклассингом уже почти получилось, только нужно к WM_VSCROLL еще WM_SIZE приделать.
    но чует мое сердце, что можно как-то хитро-хитро сделать нужный размер, а не тот который по умолчанию :) через манипуляции с nmin, nmax и npage
     
  12. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    конечно можно, просто учти что размер движка пропорционален соотношению nPage к nMax-nMin и при этом max nPos = nMax - nPage, но лично меня "нулевой" размер в качестве минимального вполне устраивал потому его и посоветовал ;)
     
  13. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    кстати если в SetScrollInfo делать:
    lpsi.nMax = lpsi.nPage;
    lpsi.nPage = 0;
    lpsi.fMask = SIF_PAGE | SIF_RANGE

    то у меня скролл вообще не появляется, только мелькает изредка. у меня работает только при lpsi.fMask = SIF_PAGE

    это у меня неправильное что-то или так и задумано?
     
  14. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Если nMin = 0, а nMax <= nPage - то scrollbar-у некуда бегать потому то он и исчезает, правда у тебя задан LBS_DISABLENOSCROLL, т.е. по идее он должен в этом случае не исчезать, а становиться серым.
     
  15. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    nMax <= nPage - не получается, потому что следом идет
    nPage = 0
     
  16. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Хм - точно - похоже глюк ListBox или самих полос - она не исчезает, а убегает за границу контрола, эффект проявляется только когда нет второй (горизонтальной) полосы прокрутки, если горизонтальная есть но спрятана потому что nPage >= nMax-nMin то и вертикальная из контрола не убегает ;)
     
  17. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    ух как сложно.
    а если я сделаю все, чтобы она не убегала (включу горизонтальную), то будет бегунок на вертикальной доходить до самого низа? а то сейчас когда доводишь до низа и отпускаешь, он подпрыгивает, как раз на высоту горизонтальной полосы.
     
  18. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Попробовал ещё - иногда убегает (но чуть чуть видно) иногда совсем исчезает независимо от количества полос - какие-то странные глюки ListBox.
    Проверил на ListView - всё в порядке, да и на своём окне никогда ни с чем подобным не сталкивался.
     
  19. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    да я listview и начал, но как же там муторно все и сколько лишнего, хотя, скорей всего к нему и вернусь :dntknw:
    а в listview до самого низа бегунок доходит или тоже вверх подпрыгивает когда мышь отпустишь?
     
  20. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    А ты не забываешь делать nMax = nMax - nPage перед nPage = 0 (см #4)?
    Подпрыгивает он от того, что nPos соответствует верхней грани бегунка, "упирается" в nMax он нижней гранью, а потом ты его сокращаешь в размерах как раз на размер этого пробела.
    Или если изменяешь nPage не на ноль, а на свой размер, то вычитай разницу между исходным и новым размером nPage