[file=192200]
добавил внутрь dll самостоятельную обработку события отсоединения dll от вызывающего потока, а именно закрытие всех хуков-сабклассинга (полчаса нет вылетов по ранее найденым уязвимым точкам - осталось постучать по дереву на всякий случай)
MouseWheeL_2026-06-29_19-36_Scroll_DLL-коррект_закрытие.rar
слишком много точек обрыва связи с мышью понаставил что иногда при переходе с формы на форму с закрытием предыдущей иногда происходит полное обрывание всех связей с мышью.
Решение - отключил проверку текущего существования дескриптора, оставил обработку освобождения адресного пространства dll вследствии закрытия процесса хозяина и добавил повторную привязку мыши по КЛИКУ левой кнопкой мыши по окошку контрола MouseScrollEvent.ctl (клик позволяет восстановить привязку если элемент связи завис - закрывает и открывает связь заново)
лучше уж иногда (редко) пусть зависает связь контрола с мышью, чем зависает весь проект
Neirapik
А чем твоя прога лучше существующих?
Nigesky
"существующих" ? - не нашёл
не знаю как в других языках но в VB6 нет ни события колёсика мыши ни самого такого понятия. Неделю искал в инете хоть что нибудь про получение событий колеса мыши. потом решил что проще (и быстрее) сделать самому!
И встречный вопрос про ссылку на существующие - если я не прав то буду рад
Neirapik
Ну как вариант можно использовать DirectInput для обработки событий мыши, только с C++ придется переписывать на VB6
Directx на VB6 - сложный случай
Алиса:
Фокус окна. Если окно с приложением теряет фокус, DirectInput может перестать присылать данные. В таком случае нужно заново вызывать
Acquire()
Вывод
Для обработки прокрутки колёсика мыши в большинстве прикладных задач (не игры с низкоуровневым вводом) проще и эффективнее использовать стандартные механизмы Windows (сообщения
WM_MOUSEWHEEL
). DirectInput имеет смысл применять, только если вам критически важна максимальная низкоуровневая абстракция (например, для специализированных игровых контроллеров).
И да для специализированных игровых контроллеров и максимальная низкоуровневая абстракция - там да, но зачем городить огород если нужно узкоспециализированое событие с буфером изменений.
обобщаю:
DirectInput - массивное с кучей своих правил на все случаи жизни и правил доступа к себе (и в VB6 к нему не просто подступиться).
MouseWheel_DLL.dll - использует тот же механизм очереди событий что и DirectInput, но вызывается гораздо проще и насчёт фокуса - при возврате фокуса окну поток сообщений для окна сам возобновляется!
если ещё проще - видит мышь Windows то и MouseWheel_DLL.dll её тоже видит и вся работа сводится к 3 методам из dll плюс много буферов событий (внутри dll) для каждого дескриптора свой
Ну и я не пишу видеоигры (там скорее всего Directx и вправду удобнее - не знаю) а вот со всяким интерфейсом приходиться работать.
_______________________
ещё один ответ Алисы:
Важный нюанс
Хотя DirectInput и работает с HID, его использование для мыши и клавиатуры сейчас не рекомендуется. Дело в том, что он создаёт дополнительный поток для опроса, что добавляет накладных расходов. Для управления курсором и обработки кликов гораздо удобнее и естественнее использовать стандартный цикл сообщений Windows (сообщения
WM_MOUSEMOVE
). DirectInput же даёт преимущества в основном для сложных устройств, например, джойстиков с обратной связью. learn.microsoft.comen.wikipedia.org*gamedev.netlearn.microsoft.comlearn.microsoft.com
Если вы сейчас пишете новый проект, советую рассмотреть альтернативные подходы, например, работу с Raw Input API.
________________________
ну и как вижу я:
событие к-са мыши <- DirectInput(массивный+куча правил+поддержка в яз прог) <- Windows очередь
событие к-са мыши <- dll (маленькая+простота подкл. в любом языке програмир) <- Windows очередь
(ну и dll самодостаточная в виде 1-го файла)
________________________
Что-то из дома сайт практически перестал открываться, нормально писать могу только с работы.
Neirapik
> DirectInput имеет смысл применять, только если вам критически важна максимальная низкоуровневая абстракция (например, для специализированных игровых контроллеров
Для мыши тоже, если, например, хочется избавиться от промежуточных "улучшений", вносимых Windows, типа "повышение точности указателя". Но для прокрутки колеса действительно, Win API достаточно.
Другое дело - COM dll и всякие хуки. На сколько это надёжно? На сколько безопасно?
Mikle
Другое дело - COM dll и всякие хуки. На сколько это надёжно? На сколько безопасно?
последнюю неделю как раз проверял опасность применения хуков (насмотрелся на зависание проекта)!!!!!!!!
вывод:
в VB6 хук использовать никак нельзя т.к. это язык высокого уровня который может притормозить весь процесс выполнения для отладки, а хук надо обрабатывать строго в реальном времени
в dll можно т.к. подпрограмма ответа на хук висит в памяти на своём постоянном адресе и всегда гарантированно ответит на обратный вызов в реальном времени, но тут тоже подводный камень - время существования дескриптора на который приходит ответ - решил применением такого Windows-кого стандартного для dll сообщения (Windows сама сообщает в dll):
CASE %DLL_PROCESS_DETACH
' Очистка
MouseDllUnHook 0,nn0 'отключение ВСЕХ хуков
'Print "DLL detached" но иногда (очень редко) в VB6 для dll почему то появлятся эта команда без закрытия всего проекта тут уже решение как снова поставить отменённый хук пока через костыль перепривязка по клику левой кнопкой по окошку котрола мыши - если проект действительно закрыт то и кликнуть по окошку не получится (из-за отсутствия окошка) да и не надо!
В целом получается так что dll полностью самостоятельно обрабатывает события хуков в реальном времени и пишет изменения в свой локальный буфер (отдельный для каждого дескриптора на котором хук) и больше ничего не делает - только по запросу из вне с указанием дескриптора присылает текущее состояние буфера для указаного дескриптора
забыл сказать что:
MouseDllUnHook 0 (Me.MouseScrollEvent1.a_InitStop 0) =отключение ВСЕХ хуков, а не одного
Me.MouseScrollEvent1.a_Init Me.hwnd 'поставить хук на указаный дескриптор Me.MouseScrollEvent1.a_InitStop 'убрать хук с ранее указаного дескриптора Me.MouseScrollEvent1.a_InitStop 0 'убрать все хуки
MouseWheel1.MouseDllGetCountScroL hWhd, LocalSumScroll, x, y 'текущие состояние из локального буфера для указного дескриптора: кол-во поворотов для дескриптора и координаты относительно дескриптора, относительно экрана, а относительно _add привязаных уже от верхнего левого угла дескриптора объекта xObj, yObj
применение dll позволяет отвязать от применяемого языка программирования сам процесс обработки хуков! плюс самостоятельное автозакрытие всех хуков при отсоеденении dll
в последних версиях ещё добавил отключение хука перед формирование события скрола из контрола на форму и обратное включение хука как только программа на форме закончит выполнять свою реакцию на событие
три дня полёт нормальный :)
'если замечено изменение кол-ва движения колёсика мыши то далее делаются события
nTi = Timer1.Interval 'запоминаем скорость таймера
Timer1.Interval = 0 'отключаем таймер
MouseWheel1.MouseDllUnHook nMehWhd, iScr 'отключаем хук мыши и запоминаем iScr=SumScroll
RaiseEvent MouseScroll((SCount , SumSCount, x , y) 'событие скролла для всей формы
If FindObject(Out_Index, Out_hWhd, Out_xObj, Out_yObj) Then
'для доп контрола доп событие
'событие для например: Me.MouseScrollEvent1.a_InitFormObject_Add Me.VScroll1.hwnd
'генерируется если координаты мыши над дополнительным (_add hwnd) контролом
RaiseEvent MouseScrollObject(SCount , SumSCount , x, y, ObjectIndex, Object_hWhd , xObj, yObj)
End If
Timer1.Interval = nTi
MouseWheel1.MouseDllHook nMehWhd, iScr 'включаем хук мыши обратно с занесением SumSCount такого какой был на момент отключенияхотя в принципе такое внутри MouseScrollEvent1 отключение включение хука избыточно - но так спокойнее (мало ли что пользователь сделает) :)
Neirapik
Поменьше Алису слушай. Вариант с DirectInput вполне рабочая схема.
Nigesky
Поменьше Алису слушай. Вариант с DirectInput вполне рабочая схема.
не слушаю а читаю, и потом смотрю ссылки откуда было накопано ну и дальше иду вниз по странице поиска
про Direct уже выше говорил что не спорю про его сильные и слабые стороны так как в моём случае (VB6) он просто труднодоступен для меня, и задача у меня ставилась сделать дополнение именно для языка программирования, дополнение максимально простое и легко применимое во всех проектах
для объективности попробую в свободное время DirectInput покопать - но это новая для меня тема так что не знаю сколько времени уйдёт :)