powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Как в форме поймать событие Scroll?
25 сообщений из 57, страница 1 из 3
Как в форме поймать событие Scroll?
    #39514778
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Цитата из статьи:

Можно инициировать событие Scroll, выпустив метод Scroll для формы, кадра или страницы. Пользователи могут генерировать события Scroll, перемещая ползунок.

Ссылка на эту статью:
https://msdn.microsoft.com/ru-ru/library/office/gg251461.aspx

Вопрос как инициировать событие Scroll?
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39514784
guest_rusimport
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JavaStudent,
может из этого что пригодится
Считывание и установка позиции скроллбаров у формы Access
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39514785
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
guest_rusimport, код 14 летней давности пугает. Я пытался засунуть это в форму... Сходу не получилось...

Я хочу сделать, чтобы при движении scrolla вправо, двигалось поле в подчиненной форме вправо. В статье есть строка - "инициировать событие Scroll" ... Как его иницировать...?
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39514818
guest_rusimport
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JavaStudentЯ хочу сделать, чтобы при движении scrolla вправо, двигалось поле в подчиненной форме вправо...
Так в чём проблема? См. приложенный пример с использованием приведенного кода по ссылке. (Не знаю, заработает ли в твоей версии Access ... ну, вот, заодно и проверишь)
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39514970
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Скачал, БОЛЬШОЕ спасибо. Работает. Попробую к себе прикрутить.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39514998
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2007 Access не работает. Не находит crossbar в форме:

If StrComp(s, "SCROLLBAR", vbTextCompare) = 0 Then

Сюда не заходит, т.е. нет в детях скроллбара.... и перебор всех детей формы их там не 3...

style& = GetWindowLong&(hwndChild, GWL_STYLE)
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39515006
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поменял на дитя: NUIScrollbar заработал пример.

If StrComp(s, "NUIScrollbar", vbTextCompare) = 0 Then

Только вот таймер для проверки положения скролл устанавливать не красиво...

Как поймать событие движения скролла?

Двигается скролл вправо - двигается поле вправо.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39515008
guest_rusimport
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JavaStudent2007 Access не работает. Не находит crossbar в форме:

If StrComp(s, "SCROLLBAR", vbTextCompare) = 0 Then

Сюда не заходит, т.е. нет в детях скроллбара.... и перебор всех детей формы их там не 3...

style& = GetWindowLong&(hwndChild, GWL_STYLE)

в комментарии к статье же было -
надо заменить на
If StrComp(s, "NUIScrollbar", vbTextCompare) = 0 Then

пробуй
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39515014
guest_rusimport
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JavaStudentПоменял на дитя: NUIScrollbar заработал пример.

If StrComp(s, "NUIScrollbar", vbTextCompare) = 0 Then

Только вот таймер для проверки положения скролл устанавливать не красиво...

Как поймать событие движения скролла?

Двигается скролл вправо - двигается поле вправо.

некрасиво, зато просто и надежно... другой путь - субклассирование , ловить сообщение окна формы WM_HSCROLL
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39515017
guest_rusimport
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JavaStudent,

пример субклассирования 3367169 (переделай под свой случай)
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39517874
Вакшуль Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
guest_rusimport,
guest_rusimportдругой путь - субклассирование , ловить сообщение окна формы WM_HSCROLL
а я как раз недавно подобным и занимался - 20774213


JavaStudent,

В общем, взял этот пример за основу, переделал на скорую руку за 1,5 часа. Вроде работает. Если что - можно подправить.
Но я бы, наверно, применял бы таймер. Куда более безопасней чем субклассирование. И там и там функции обратного вызова, какая по большому счету разница?

Пример во вложении. Три версии: Scroll_2000.mdb, Scroll_32-bit.accdb, Scroll_64-bit.accdb
Запустите на выполнение не открывая редактор кода. В ролике поста, на который сослался выше и в самом коде файла объяснил почему придется соблюдать более жесткие правила, субклассируя форму. Нельзя открывать редактор IDE, если в этот момент идет субклассирование. Откроете - завесите Access. Если хотите посмотреть код или редактировать, сначала закройте формы, по которым запущено субклассирование, а только потом открывайте среду IDE. В этом примере я тоже ввел константу, определяющую режим отладки. Здесь она называется Scroll_DebugMode. Если хотите отлаживать и писать свой код, установите ее значение в True. Тогда Access будет работать стабильно, т.к. перехвата событий прокрутки не будет. А чтобы посмотреть как работает ваш код, установите Scroll_DebugMode = False, закройте проект и запустите, помня, что теперь редактор кода открывать нельзя. Захотите открывать - снова закройте все формы, по которым запущено субклассирование и тогда открывайте. Но открыв среду IDE хоть раз, запускать проект на выполнение, если Scroll_DebugMode = False нельзя, - завесите Access.

Я обращался и на Stackoverflow и на Social.msdn:
https://stackoverflow.com/questions/45854403/i-cant-subclass-ms-access-form-if-the-window-of-ide-has-been-opened?noredirect=1#comment78705743_45854403
https://social.msdn.microsoft.com/Forums/office/en-US/4cf1d113-d905-4cdf-9f82-eb2c8d3666ed/setwindowlong-on-a-ms-access-form-what-happens-if-ide-window-is-open?forum=accessdev
в надежде, что подскажут, как работать без риска краха, но ответа нет.

На Stackoverflow мое внимание обратили на нежелательность использования SetWindowLong, с предпочтением в пользу применения SetWindowSubclass. Мне сложно это комментировать. Я просто решил сделать как советуют:
IInspectableSubclassing controls using SetWindowLong has been wrong since the first 64-bit Windows OS (Windows XP 64-Bit Edition, released in 2001). Likewise, subclassing controls using SetWindowLongPtr has been wrong for more than a decade and a half (see Subclassing Controls for the safe and sane alternative). – IInspectable Aug 24 at 19:56
И адресовали меня вот сюда:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183.aspx?f=255&MSPPError=-2147217396
А тут действительно Microsoft ратует за использование SetWindowSubclass.

Хотя, что интересно. Когда в тестах я использовал SetWindowLong, то в этом случае не нужно было ждать пока форма загрузится полностью. Там не нужны были вот эти финты с таймером - 20780320 , в то время как используя SetWindowSubclass субклассировать форму можно только, как я говорил, тогда, когда она полностью загружена, иначе, Access падает.
Но я все равно остановился на SetWindowSubclass, почитав, что многие расхваливают эти API функции, мол, это безопасный подход, к тому же примеры с SetWindowLong, которые я видел, все используют Lib "user32", а как это будет работать на 64-bit, да, и вообще, что там дальше с судьбой этой Lib "user32", не понятно.

У меня вообще-то есть еще мысли как можно было бы попробовать сделать по-другому. Если найду время - попробую, расскажу.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39518380
Относительно прокрутки и сабклассинга - думается, 10808021 можно доработать, инфраструктура там есть. Там часть вопросов, с которыми Вакшуль Сергей столкнулся, решена с помощью низкоуровневой фильтрации сообщений (прикол, однако, в том, что для .mde/.accde таких ухищрений не нужно, достаточно простых вариантов типа упомянутого 3367169 ).
Ещё несколько комментариев для понимания, какие могут быть проблемы (часть) и как решать:
7280562 п. 4)
8512604 .
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39521447
Вакшуль Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
20780341 код в этом примере чего-то конечно ловит, но только процентов 15 возможных ситуаций. И эти 15% требуют доработки.
Вакшуль СергейУ меня вообще-то есть еще мысли как можно было бы попробовать сделать по-другому. Если найду время - попробую, расскажу.
Я сделал по-другому. Без субклассирования окна формы. Т.е. редактор кода может быть открыт.
Перехватываются и обрабатываются:
- прокрутка формы при клике по полосе прокрутки
- прокрутка формы колесиком мыши
- прокрутка формы при использовании middle button(нажатие на колесико и удерживание)
- прокрутка формы в результате смены фокуса, как при использовании клавиатуры(tab, стрелки и т.п.), так и мыши. Тот случай, когда прокручивание происходит в результате получения фокуса контролом, который частично или полностью не виден, выходя за границы формы

Не обрабатывается:
- горизонтальная прокрутка формы, вызываемая наклоном колесика в сторону(tilt) мыши Microsoft
События мыши перехватываются с помощью SetWindowsHookEx. Особенность функции в том, что системные сообщения о наклоне колесика мыши в сторону(tilt) эта функция не перехватывает. К сожалению. Во всяком случае сообщения моей мыши Microsoft не перехватываются.

Плохо обрабатывается:
- прокрутка формы при использовании middle button(нажатие на колесико и удерживание). В принципе работает, но возможна ситуация, когда клики вниз и вверх уже отработали, а форма "разогнавшись" продолжает прокручивание и останавливается когда ей заблагорассудится. Я заложил для борьбы с этим определенное время ожидания, но, как уже сказал, событие может не перехватится.

В целом пример рабочий, но как и предлагал guest_rusimport, гораздо проще просто обойтись таймером.

Во вложении два файла: accdb32-bit и mdb2000. mdb2000 на XP не работает. Там низкоуровневые сообщения мыши не перехватываются. Но на семерке mdb2000 работает.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39546444
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вакшуль Сергей, Я не смотрел еще код, но выглядит красиво. Не разобрался почему h=2 при крайнем левом положении бегунка, но то, что удалось отловить самый левый номер столба и самый верхний номер строки в зависимости от положения ползунка, которые видны прикольно.

Выглядит так. Лифт(бегунок) поехал вниз, а лампочка горит на 12 этаже. Лифт(бегунок) остановился лампочка загорелась сразу на 1 этаже...

Но пример, мне очень понравился. Спасибо.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39546455
Вакшуль Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JavaStudent,
JavaStudentНе разобрался почему h=2 при крайнем левом положении бегункаЭто просто факт. Не знаю есть ли тут логика. У подчиненной формы крайнее значение, считываемое функцией GetScrollPos, действительно не равно нулю, но очень близко. А вот у основной формы крайние значения полос прокрутки таки равны нулю. Остается только констатировать это явление :)

JavaStudentто, что удалось отловить самый левый номер столба и самый верхний номер строки в зависимости от положения ползунка, которые видны тут не понял. Вы имеете ввиду, что вы у себя реализовали такой функционал?

Вакшуль СергейПлохо обрабатывается:
- прокрутка формы при использовании middle button(нажатие на колесико и удерживание). В принципе работает, но возможна ситуация, когда клики вниз и вверх уже отработали, а форма "разогнавшись" продолжает прокручивание и останавливается когда ей заблагорассудится. Я заложил для борьбы с этим определенное время ожидания, но, как уже сказал, событие может не перехватится.
Уже потом, когда описывал плюсы и минусы решения, понял как можно устранить описанный выше недостаток. Если очень, очень надо могу доработать код в этом плане. Просто так - не хочется.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39547038
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вакшуль Сергей,

VScroll = False HScroll = True fsbSub_ScrollPos v = 5, h = 3

v=5 - это 1 видимая строка
h=3 - это 1 видимый столб

Ваш пример оценил и понравился. Пока не реализовал у себя. В идеале ловить v = 5, h = 3 при движении бегунка, а не при его отпускании. Позже поковыряюсь в вашем коде.

Но себе взял на вооружение.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39547098
Вакшуль Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JavaStudent,
вы правы, там действительно оказывается :) есть связь между значениями v/h и номерами видимых строк/столбцов
я даже не обратил на это внимание. Вернее, напрочь забыл.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551283
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вывод такой. Поймать событие скролл нельзя. Более того при перемещении мышки вдоль линии прокрутки, событие перемещение не происходит. Ни события click, ничего. Мышка попадает в пустоту.

Использовать Hook не хочется. Я как понял он грузится и начинает слушать все события, я не разбирался только в форме или вообще
все приложение.

Использовать таймер, надо знать координаты ползунка (для определения взял код из примера Сергея Вакшуль)

Запускаю в событии таймер так

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
Dim v As Long
Dim h As Long
Call GetScrollBarPos(Me("Экран").Form.hWnd, v, h)
If Me("Экран")("region").Left = PixelToTwip(h) Then
Else
   Me("Экран")("region").Left = PixelToTwip(h)
End If



Координаты выплевывает в Пикселях, нужно переводить в Твипы
Определяет очень точно.

Недостаток, то что каждую секунду запускается таймер, который проверяет положение ползунка...

Не ожидал такого от Access.... Везде есть работа с ползунком, а в Access Нету...

Очень хороший подводный камень Access. Ударился больно.
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551290
MrShin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JavaStudent,

Увы и ах. Таймер - смерть условному форматированию и вычисляемым полям, начинают работать просто ужасно - ну нет в Аксе многозадачности. Хуки - нормальное обходное решение, особого влияния на производительность не оказывается, так что не гнушайтесь
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551304
Фотография Панург
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JavaStudentВывод такой. Поймать событие скролл нельзя. Ээмуляция табличной формы
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551374
Вакшуль Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JavaStudentИспользовать Hook не хочется. Я как понял он грузится и начинает слушать все события, я не разбирался только в форме или вообще все приложение.Насчет примененной у меня функции SetWindowsHookEx.
Используемый тип процедуры фильтра - WH_MOUSE_LL, т.е. мониторятся не все сообщения, а только "low-level mouse input events".
Этот же тип определяет и область мониторинга: "Global only", т.е. слушаются клики не только внутри приложения.
Также нужно иметь ввиду, что перехватив сообщение, долго тянуть с его обработкой нельзя. MSDN на этот счет говорит следующее:
авторThe hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value in the following registry key:
HKEY_CURRENT_USER\Control Panel\Desktop
The value is in milliseconds. If the hook procedure times out, the system passes the message to the next hook. However, on Windows 7 and later, the hook is silently removed without being called. There is no way for the application to know whether the hook is removed.
Я собственно ни к чему не призываю. Решайте сами. В реальном бою свой код не проверял, а комментарии MrShin насчет использования таймера вы видели.

По поводу области действия, "Global only". Да, хотелось бы, что бы фильтр был наложен внутри потока, но, увы. Я немного поэксперементировал с другими типами фильтра: WH_MOUSE, WH_MSGFILTER и, по-моему, WH_CALLWNDPROC, область действия которых "Thread or global", но ничего там толком не добился, использовать их в решении у меня не получилось. А вот с WH_MOUSE_LL все как по маслу. Ну да, он глобальный, но посмотрите код, там в два коротких шага(WindowFromPoint и GetAncestor) проверяется пришелся ли клик на окно Access или на другое приложение. Если в другое, сразу выход. Работая не в Access, а снаружи, влияния эти двух шагов на действия мыши, я не заметил. Вообще было ощущение, что приоритет Access ушедшего в фон резко понижен, установленный фильтр никак себя не проявлял. Хотя работая внутри Access я заметил некоторое подтормаживание при попытке выделения текста мышкой(в самом начале этого движения).
В принципе, в момент переключения в другое приложение, фильтр можно снять, а при возвращении - восстановить. Например, поставив еще один хук :), отслеживающий переключения между приложениями/окнами. Я даже сделал набросок, но потом, взвесив, решил, что преимущества ничтожны и вообще спорны (вы действительно не заметите работая извне, что Access, находящийся в фоне, фильтрует сообщения мыши).

Но вот о чем, действительно, мне кажется, нужно позаботится, так это о том, чтобы handle установленного фильтра, сохраненный в переменной, не был потерян, если в результате неперехваченной ошибки выполнения глобальные переменные "слетят". Если его сохранять в Tempvars, то проблем не будет. Я проверял. Tempvars работает железобетонно. В коде не использовал Tempvars только потому, что думал о совместимости с предыдущими версиями Access. А зря. На XP в 2000-ом применить SetWindowsHookEx все равно не получилось.
Если опасаетесь, что ваша программа зависнет, процесс придется снять, а установленный фильтр по-прежнему будет мучить систему, то опасения напрасны. Фильтр будет снят системой.
У меня в коде фильтр на сообщения устанавливается и удерживается ровно столько, сколько открыта форма, чья прокрутка отслеживается. Вы можете сделать еще жестче и снимать фильтр, если форма деактивируется(хотя если форма всплывающая, то отследить это проблемно), и устанавливать при ее активации.

Остальные комментарии по теме я оставил тут: 20797575 20897125 20899090 20899392 .
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551414
Predeclared
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JavaStudent... Двигается скролл вправо - двигается поле вправо.
Никак не соображу цель этого перемещение.
Скриншотом формы не поделитесь?
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551779
JavaStudent
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подчиненная ленточная форма. 31 квадратик (2 см на 2 см) в строке. 44 строки. 1 колонка, например, наименование стран. Двигаю бегунок.
Наименование стран пропадает. Определяю положение бегунка - двигаю первый столбик. Но таймер очень плохое решение...
Другого, пока нет...
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551785
_гурД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JavaStudent,
если, как вы пИшите, плохо работает только в подчинённой форме -
то, может, переделать её на главную?..
...
Рейтинг: 0 / 0
Как в форме поймать событие Scroll?
    #39551788
_гурД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что касается наименований государств в международных и внутренних документах,
по у каждой страны есть "нормативный алиас" (даже вроде два). Не помню, как это наз в документе, на практике стречались: Russia - RU, RUS...
??
...
Рейтинг: 0 / 0
25 сообщений из 57, страница 1 из 3
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Как в форме поймать событие Scroll?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]