Neirapik
> работает только один экземпляр
А если каждому контролу свой hWnd делать? А то они все к hWnd формы обращаются.
SetLockRect
агась! в точку! и ошибка пропадает :)
свой hWnd делать? попробую
форма с объектом встала поверх всех и продолжает работать, а на всё остальное теперь фокус не возвращается пришлось закрывать через диспетчер задач, попробую варианты
сейчас не виснет но и по прежнему работает только последний открытый экземпляр
попробовал открывать и закрывать формы с Userконтролом мыши работает по прежнему последний и через минуту формы опять зависли кроме последнего контрола который продолжал показывать счётчик
в моём не зависающем способе (после целой пары дней работы) форма запрашивает в модуле мыши хук (и при закрытии соответственно UnHook) только фишка в том что модуль при отлавливании события мыши не создаёт событие для окна, а вместо этого меняет счетчик колеса в переменной внутри массива где отдельные элементы являются счётчиками колёсика для каждого окна которое запросило хук и окно уже само когда ему надо запрашивает из модуля значение своего счётчика.
Таким образом обработка события мыши в модуле происходит максимально и ГАРАНТИРОВАНО быстро (для избежания зависания очереди событий Windows) без оглядки на окно
массив счётчиков внутри модуля
попутал хук формы и хук окна, внутри UserControl хук лучше не делать так как на стадии проектирования контролы уже работают в своём потоке и хук до запуска программы вызывает дёрганье редактора IDE .
Хотя как ни странно сложный UserControl с хуком мыши внутри не вызывает дёрганье редактора - надо будет разобраться в чем фокус
Neirapik
Тут всё дело в том, что чей обработчик первый опросил MouseWheel, тот и сбросил очередь событий, следующему уже не достанется.
Контролы с hWnd должны иметь своё окно, а не быть невидимыми, как таймер. И только над этим окном будет срабатывать MouseWheel для этого контрола.
На форме два PictureBox, pic1 и pic2, всё работает:
Option Explicit
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (ByRef lpMsg As WinMSG, ByVal hWnd As Long, ByVal uMsgFilterMin As Long, ByVal uMsgFilterMax As Long, ByVal uRemoveMsg As Long) As Long
Private Declare Function WaitMessage Lib "user32" () As Long
Private Type WinMSG
hWnd As Long
uMessage As Long
wParam As Long
lParam As Long
dwTime As Long
mX As Long
mY As Long
End Type
Const PM_NOREMOVE As Long = 0
Const WM_MOUSEWHEEL As Long = &H20A
Const PM_REMOVE As Long = 1
Dim MSG As WinMSG
Dim Wheel As Long
Private Sub Form_Load()
Me.Show
While DoEvents
WaitMessage
If PeekMessage(MSG, pic1.hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE) Or PeekMessage(MSG, pic2.hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE) Then
If MSG.wParam < 0 Then
Form_MouseWheel -1
Else
Form_MouseWheel 1
End If
End If
Wend
End Sub
Sub Form_MouseWheel(ByVal nScroll As Long)
Wheel = Wheel + nScroll
Me.Caption = Wheel
End Subсделал контрол колёсика мыши
с вышеприведённым примером окно с двумя PictureBox работает хорошо но снова не закрывается - при закрытии открывается снова
сейчас обкатываю только что сделанный контрол который формирует события мышки для формы
Проверил свой контрол - работает и позволяет закрывать форму. События для формы ловятся только когда форма в фокусе как и требовалось!
Neirapik
> с вышеприведённым примером окно с двумя PictureBox работает хорошо но снова не закрывается - при закрытии открывается снова
У меня, что этот пример, что прошлый, дают закрывать форму. Может в настройках формы что-то накручено, или ещё что-то есть в коде, например, Form_QueryUnload? У меня новый проект по умолчанию, добавлены две формы, всё.
проверил контрол на нескольких формах - работает не мешая друг другу, из особенностей - надо в Form_Load вызвать один раз процедуру a_Init передавая в контрол hWhd формы
Private Sub Form_Load()
Me.MouseScroLEvent1.a_Init Me.hWnd
End Sub
отмену хука при закрытии формы контрол делает сам
событие при повороте колёсика выглядит так:
Private Sub MouseScroLEvent1_MouseScroLLL(ByVal SCount As Long, ByVal SumSCount As Long)
'SCount - на сколько сейчас сдвинулось колёсико
'SumSCount сколько всего колёсико накрутило
Me.Caption = Format(SumSCount)
End Sub
и да я пока не добавил x y - потом добавлю
цитата
Mikle
#308
11:48, 16 июня 2026
Neirapik
> с вышеприведённым примером окно с двумя PictureBox работает хорошо но снова не закрывается - при закрытии открывается снова
У меня, что этот пример, что прошлый, дают закрывать форму. Может в настройках формы что-то накручено, или ещё что-то есть в коде, например, Form_QueryUnload? У меня новый проект по умолчанию, добавлены две формы, всё.
_________________________________________________
ответ:
попробую создать новый проект может там закроется
в одном экземпляре форма закрылась, попробую две где одна открывает вторую в которой уже скролл
ВОООТ оно
Private Sub Command1_Click()
Form1.Show
End Sub
где Form1 это форма со скролом и открываю её из Form2(в этой форме нет скролинга), после этого Form1 не закрывается, а если закрыть Form2 и потом Form1 то возникает ошибка времени исполнения на это строке:
If PeekMessage(MSG, Pic1.hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE) Or PeekMessage(MSG, Pic2.hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE) Then
и закрыть форму можно теперь только закрыв проект
а теперь умудрился словить вылет со своим контролом во время постановки выполнения на паузу в момент закрытия формы с контролом
поправил - важно чтобы не было ошибки в форме в момент закрытия формы - ошибка вызыает постановку выполнения на паузу и эта пауза как то фатально действует вызывая зависание проекта
видимо форма уже уничтожена а контрол ещё нет т.е. получается хук на форму которой уже нет. Хм надо попробывать завязать на UserControl.hWhd
Не прокатило - перехват проходит только пока фокус на контроле(хм а это не баг а фича в случае если скролинг нужен только в пределах контрола а не всей формы) а не на форме, попробую добавить отмену хука в событие закрытия формы (до этого контрол закрывал хук по событию своего закрытия а не формы) добавил, и теперь использования контрола с событием колёсика надо делать так:
Private Sub Form_Load()
Me.MouseScroLEvent1.a_Init Me.hWnd
End Sub
Private Sub Form_Unload(Cancel As Integer)
Me.MouseScroLEvent1.a_InitUnLoad
End Sub
всё! на это ноте сегодня отдыхать
P.S. Mikle твой метод перехвата события колёсика мне не знаком - Спасибо! узнал новое
P.P.S. готовый контрол с событием скрола потом выложу после причёсывания и тестов
упс только сейчас подумал что надо сделать отдельную тему про этот контрол :-J