Что нового

MouseOnEvent - Обработка событии мышки

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
AutoIt: 3.3.6.1 - 3.3.14.1
Версия: 2.3
Категория: Мышь и клавиатура
Описание: Позволяет установить обработку событии мышки. Кроме прочего, поддерживает блокировку событии в определённом окне.

Примечания:
  • Библиотека (при использовании функции _MouseSetOnEvent_RI) регистрирует сообщение $WM_INPUT, может вызвать конфликт с другими библиотеками/скриптами.
  • Не смешивайте использование _MouseSetOnEvent и _MouseSetOnEvent_RI, может вызвать непредсказуемое поведение.
  • Блокирование функции события $sFuncName вызовом системных диалогов типа "Msgbox()", может привести к неожиданным последствиям,
    возврат в систему должен выполниться как можно раньше!
  • При указании события $MOUSE_PRIMARYDOWN_EVENT и $MOUSE_SECONDARYDOWN_EVENT,
    событие $MOUSE_PRIMARYDBLCLK_EVENT и соответственно $MOUSE_SECONDARYDBLCLK_EVENT также устанавливается принудительно,
    чтобы отключить отлов этих событии, используйте
    Код:
    _MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT)
    ;или
    _MouseSetOnEvent($MOUSE_SECONDARYDBLCLK_EVENT)
  • При использовании обфускатора/Au3Stripper, убедитесь что функции события добавлены в список игнорирования (#Obfuscator_Ignore_Funcs/#Au3Stripper_Ignore_Funcs).

Пример:
Код:
#include <GUIConstantsEx.au3>
#include "MouseOnEvent.au3"

HotKeySet("{ESC}", "_Quit")

_Example_Intro()
_Example_Limit_Window()

Func _Example_Intro()
	MsgBox(64, "Attention!", "Let's set event function for mouse wheel *scrolling* up and down", 5)
	
	;Set event function for mouse wheel *scrolling* up/down and primary button *down* action (call our function when the events recieved)
	_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_MouseWheel_Events")
	_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_MouseWheel_Events")
	_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event")
	
	Sleep(3000)
	
	;UnSet the events
	_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT)
	_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
	
	ToolTip("")
	
	MsgBox(64, "Attention!", "Now let's disable Secondary mouse button up action, and call our event function.", 5)
	
	_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_MouseSecondaryUp_Event", 0, 1)
	Sleep(5000)
	_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT)
	
	ToolTip("")
EndFunc

Func _Example_Limit_Window()
	Local $hGUI = GUICreate("MouseOnEvent UDF Example - Restrict events on specific window")
	
	GUICtrlCreateLabel("Try to click on that specific GUI window", 40, 40, 300, 30)
	GUICtrlSetFont(-1, 12, 800)
	GUICtrlCreateLabel("Press <CTRL + Q> to exit", 10, 10)
	GUISetState()
	
	_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event", $hGUI)
	;A little(?) bugie when you mix different events :(
	;_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_MouseSecondaryUp_Event", $hGUI)
	
	While 1
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				ExitLoop
			Case $GUI_EVENT_PRIMARYDOWN
				MsgBox(0, "", "Should be shown ;)")
		EndSwitch
	WEnd
	
	_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
	;_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT)
EndFunc

Func _MouseWheel_Events($iEvent)
	Switch $iEvent
		Case $MOUSE_WHEELSCROLLDOWN_EVENT
			ToolTip("Wheel Mouse Button (scrolling) DOWN Blocked")
		Case $MOUSE_WHEELSCROLLUP_EVENT
			ToolTip("Wheel Mouse Button (scrolling) UP Blocked")
	EndSwitch
	
	Return $MOE_BLOCKDEFPROC ;Block
EndFunc

Func _MousePrimaryDown_Event()
	ToolTip("Primary Mouse Button Down Blocked")
	Return $MOE_BLOCKDEFPROC ;Block
EndFunc

Func _MouseSecondaryUp_Event()
	ToolTip("Secondary Mouse Button Up Blocked")
EndFunc

Func _Quit()
	Exit
EndFunc

Поддерживаемые константы событии:
Код:
$MOUSE_MOVE_EVENT ;Движение мышки.
$MOUSE_PRIMARYDOWN_EVENT ;Зажатие главной кнопки.
$MOUSE_PRIMARYUP_EVENT ;Отжатие главной кнопки.
$MOUSE_PRIMARYDBLCLK_EVENT ;Двойное нажатие главной кнопки.
$MOUSE_SECONDARYDOWN_EVENT ;Зажатие вторичной кнопки.
$MOUSE_SECONDARYUP_EVENT ;Отжатие вторичной кнопки.
$MOUSE_SECONDARYDBLCLK_EVENT ;Двойное нажатие вторичной кнопки.
$MOUSE_WHEELDOWN_EVENT ;Зажатие средней кнопки.
$MOUSE_WHEELUP_EVENT ;Отжатие средней кнопки.
$MOUSE_WHEELDBLCLK_EVENT ;Двойное нажатие средней кнопки.
$MOUSE_WHEELSCROLL_EVENT ;Прокручивание коллёсика средней кнопки.
$MOUSE_WHEELSCROLLDOWN_EVENT ;Прокручивание коллёсика средней кнопки вниз.
$MOUSE_WHEELSCROLLUP_EVENT ;Прокручивание коллёсика средней кнопки вверх.
$MOUSE_XBUTTONDOWN_EVENT ;Зажатие боковой кнопки (обычно это кнопки навигации).
$MOUSE_XBUTTONUP_EVENT ;Отжатие боковой кнопки.
$MOUSE_XBUTTONDBLCLK_EVENT ;Двойное нажатие боковой кнопки.
$MOUSE_XBUTTON2DOWN_EVENT ;Зажатие боковой кнопки #2 (обычно это кнопки навигации).
$MOUSE_XBUTTON2UP_EVENT ;Отжатие боковой кнопки #2.
$MOUSE_XBUTTON2DBLCLK_EVENT ;Двойное нажатие боковой кнопки #2.


Скачать: MouseOnEvent.zip

Источник: CreatoR, http://www.autoitscript.com/forum/index.php?showtopic=64738
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
Re: MouseSetOnEvent - Обработка событии мышки

Отличная идея, но почему ты игнорируешь требования Microsoft, относительно Hook функций.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
Re: MouseSetOnEvent - Обработка событии мышки

CreatoR сказал(а):
Microsoft сказал(а):
If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

Yashied [?]
А ну да, я забыл про это, UDF писал давно и на основе примерочного хука, где не все правила (условия?) хука были соблюдены. Поправил, позже перевыложу.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
Re: MouseSetOnEvent - Обработка событии мышки

Если бы не это, то он вообще бы подвесил систему.

Microsoft сказал(а):
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 does not return during this interval, the system will pass the message to the next hook.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

Обновление UDF...

v1.5 [09.10.2009]
+ Добавлено распознавание прокрутки коллёсика мышки вверх и вниз. Спасибо JRowe (http://www.autoitscript.com/forum/index.php?showtopic=103362).
* Исправлена проблема с возвращаемым значением от __MouseSetOnEvent_MainHandler - следует вызывать _WinAPI_CallNextHookEx до завершения функции (спасибо Yashied).
* Константы начинающиеся с MOUSE_EXTRABUTTON* переименованы в MOUSE_XBUTTON*, как и должно было быть изначально.
* Обновлены некоторые примеры.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

И ещё одно мелкое обновление...

v1.6 [13.10.2009]
* Исправлена проблема с высвобождением русурсов хука при выходе или при удалении последнего события (спасибо wraithdu).
 

StepanSkvortsov

Чайник
Сообщения
9
Репутация
0
Re: MouseSetOnEvent - Обработка событии мышки

Отличные функции, спасибо!

Заметил ошибку в работе при выполнении следующего скрипта:
Код:
#include <GUIConstantsEx.au3>
#include <MouseSetOnEvent_UDF.au3>
HotKeySet("{ESC}", "_Quit")
;main loop
While 1
	_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_MOUSEWHEELUP_EVENT")
	_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_MOUSEWHEELDOWN_EVENT")
	Sleep(250)
	ToolTip("")
WEnd
;tooltip if WHEEL.SCROLL.UP detected
Func _MOUSEWHEELUP_EVENT()
    ToolTip("wheel UP detected")
EndFunc
;tooltip if WHEEL.SCROLL.DOWN detected
Func _MOUSEWHEELDOWN_EVENT()
    ToolTip("wheel DOWN detected")
EndFunc
;exit from script by ESC
Func _Quit()
    Exit
EndFunc


Если прокручивать колесо, исправно всплывают соответствующие ToolTip, однако если подвигать мышкой, через пару секунд скрипт завершает свою работу. Привожу сообщения об ошибках:

Код:
C:\Program Files\AutoIt3\Include\MouseSetOnEvent_UDF.au3 (201) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
If $__MouseSetOnEvent_aEvents[$i][0] = $iEvent Or $__MouseSetOnEvent_aEvents[$i][0] = $iEvent+8 Or $__MouseSetOnEvent_aEvents[$i][0] = $iEvent+16 Then
If ^ ERROR
C:\Program Files\AutoIt3\Include\MouseSetOnEvent_UDF.au3 (201) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
If $__MouseSetOnEvent_aEvents[$i][0] = $iEvent Or $__MouseSetOnEvent_aEvents[$i][0] = $iEvent+8 Or $__MouseSetOnEvent_aEvents[$i][0] = $iEvent+16 Then
If ^ ERROR
Для справки прикладываю переменные окружения:
AutoIt3Wrapper v.2.0.1.24
AutoIt3 v.3.3.6.1
Language:0419 Keyboard:00000409 OS:WIN_7 CPU:X64 OS:X86

Надеюсь, это поможет найти и исправить ошибки. Спасибо.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

StepanSkvortsov
А зачем в цикле задавать события?

Конечно библиотека не должна так вываливаться с ошибкой...
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

Обновление UDF...

v1.8 [02.06.2010]
* Исправлена проблема связанная с установкой $MOUSE_XBUTTONUP/DOWN_EVENT и других событии.
* Исправлена проблема связанная с попыткой пользователя установить дополнительную функцию на уже установленное событие.
- Теперь имя функции и другие параметры заменяются для указанного события.
* Переименован файл библиотеки (убрано "Set" по середине и "_UDF" в конце имени).
* Косметические изменения в коде библиотеки.
* Обновление документации.
 

StepanSkvortsov

Чайник
Сообщения
9
Репутация
0
Re: MouseSetOnEvent - Обработка событии мышки

UDF версии 1.7 (пробовал и 1.6 - та же ошибка).
Согласен, в цикле не надо было делать;) Возможно, в этом и была причина...
Опробую новую 1.8, о результатах доложу.
Спасибо за оперативность:smile:


Добавлено:
Сообщение автоматически объединено:

Опробовал версию 1.8 (из цикла установку события вывел):
Код:
#include <GUIConstantsEx.au3>
#include <MouseSetOnEvent_UDF.au3>
HotKeySet("{ESC}", "_Quit")
;main loop
_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_MOUSEWHEELUP_EVENT")
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_MOUSEWHEELDOWN_EVENT")
While 1
    Sleep(250)
    ToolTip("")
WEnd
;tooltip if WHEEL.SCROLL.UP detected
Func _MOUSEWHEELUP_EVENT()
    ToolTip("wheel UP detected")
EndFunc
;tooltip if WHEEL.SCROLL.DOWN detected
Func _MOUSEWHEELDOWN_EVENT()
    ToolTip("wheel DOWN detected")
EndFunc
;exit from script by ESC
Func _Quit()
    Exit
EndFunc

Да! Изумительно работает, спасибо.
Но, мышь двигается ОЧЕНЬ медленно, с запозданием:(
Глянул на код - разобраться конечно не смог, но бросилось в глаза огромное количество IF, возможно в этом причина эффекта движения курсора "как в густом сиропе".
Попробовал реализовать аналогичную функцию на основе IsPressedUDF, цинично добавив блоки
для UP и DOWN на основе _IsWheelKeyScroll:
Код:
; #FUNCTION# ===================================================================
; Name :           	_IsWheelKeyScrollUp
;Global Const $MOUSE_WHEELSCROLLDOWN_EVENT	= 0x20A + 8 ;530
;Global Const $MOUSE_WHEELSCROLLUP_EVENT		= 0x20A + 16 ;538
;===============================================================================
Func _IsWheelKeyScrollUp()
	Local Const $WH_MOUSE_LL = 14

	Local $hCallback_KeyHook = DllCallbackRegister('__WheelKeyScrollUp_Callback', 'int', 'int;ptr')
	Local $hM_Module = DllCall('kernel32.dll', 'hwnd', 'GetModuleHandle', 'ptr', 0)

	Local $hM_Hook = DllCall('user32.dll', 'hwnd', 'SetWindowsHookEx', 'int', $WH_MOUSE_LL, _
			'ptr', DllCallbackGetPtr($hCallback_KeyHook), 'hwnd', $hM_Module[0], 'dword', 0)

	Sleep(100) ;Wait some moments until the variable is set by callback function

	If IsPtr($hCallback_KeyHook) Then
		DllCallbackFree($hCallback_KeyHook)
		$hCallback_KeyHook = 0
	EndIf

	If IsArray($hM_Hook) And $hM_Hook[0] > 0 Then
		DllCall('user32.dll', 'int', 'UnhookWindowsHookEx', 'hwnd', $hM_Hook[0])
		$hM_Hook[0] = 0
	EndIf

	If $IsWheelKeyScrollUp = True Then
		$IsWheelKeyScrollUp = False
		Return 1
	EndIf
EndFunc   ;==>_IsWheelKeyScrollUp

Func __WheelKeyScrollUp_Callback($nCode, $wParam)
	Local Const $MOUSE_WheelSCROLL_UP_EVENT = 538
	Local $iEvent = BitAND($wParam, 0xFFFF)

	$IsWheelKeyScrollUp = ($iEvent = $MOUSE_WheelSCROLL_UP_EVENT)

	Return 0
EndFunc   ;==>__WheelKeyScroll_Callback

; #FUNCTION# ===================================================================
; Name :           	_IsWheelKeyScrollDown
;===============================================================================
Func _IsWheelKeyScrollDown()
	Local Const $WH_MOUSE_LL = 14

	Local $hCallback_KeyHook = DllCallbackRegister('__WheelKeyScrollDown_Callback', 'int', 'int;ptr')
	Local $hM_Module = DllCall('kernel32.dll', 'hwnd', 'GetModuleHandle', 'ptr', 0)

	Local $hM_Hook = DllCall('user32.dll', 'hwnd', 'SetWindowsHookEx', 'int', $WH_MOUSE_LL, _
			'ptr', DllCallbackGetPtr($hCallback_KeyHook), 'hwnd', $hM_Module[0], 'dword', 0)

	Sleep(100) ;Wait some moments until the variable is set by callback function

	If IsPtr($hCallback_KeyHook) Then
		DllCallbackFree($hCallback_KeyHook)
		$hCallback_KeyHook = 0
	EndIf

	If IsArray($hM_Hook) And $hM_Hook[0] > 0 Then
		DllCall('user32.dll', 'int', 'UnhookWindowsHookEx', 'hwnd', $hM_Hook[0])
		$hM_Hook[0] = 0
	EndIf

	If $IsWheelKeyScrollDown = True Then
		$IsWheelKeyScrollDown = False
		Return 1
	EndIf
EndFunc   ;==>_IsWheelKeyScrollDown

Func __WheelKeyScrollDown_Callback($nCode, $wParam)
	Local Const $MOUSE_WheelSCROLL_DOWN_EVENT = 530
	Local $iEvent = BitAND($wParam, 0xFFFF)

	$IsWheelKeyScrollDown = ($iEvent = $MOUSE_WheelSCROLL_DOWN_EVENT)

	Return 0
EndFunc   ;==>__WheelKeyScroll_CallbackDown

Но увы, не сработало:( При это событие вращения колеса (без указания направления) исправно работает, и мышь двигается без какого-либо заметного торможения.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329

xklx

Чайник
Сообщения
50
Репутация
3
Re: MouseSetOnEvent - Обработка событии мышки

А возможно сделать чтобы работало для обеих боковых кнопок(левая и правая)?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

xklx
xklx сказал(а):
А возможно сделать чтобы работало для обеих боковых кнопок(левая и правая)?
Можно.
 

xklx

Чайник
Сообщения
50
Репутация
3
Re: MouseSetOnEvent - Обработка событии мышки

CreatoR сказал(а):
xklx
xklx сказал(а):
А возможно сделать чтобы работало для обеих боковых кнопок(левая и правая)?
Можно.
Не подскажешь как?
А то я сделал но у меня почему то что левая что правая одно и тоже
 

EvgeniyV

Чайник
Сообщения
1
Репутация
0
Re: MouseSetOnEvent - Обработка событии мышки

Есть ли другой способ перехватить событие мыши?

Не знаю из-за особенностей MouseOnEvent.au3 или моей мыши Razer, перехват срабатывает, но в играх начинаются чудеса, курсор становится практически неуправляемый.

При этом стоит задача перехватить только колесо мышки whell up\down.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: MouseSetOnEvent - Обработка событии мышки

EvgeniyV [?]
перехват срабатывает, но в играх начинаются чудеса, курсор становится практически неуправляемый.
Пример?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
Re: MouseSetOnEvent - Обработка событии мышки

EvgeniyV сказал(а):
Не знаю из-за особенностей MouseOnEvent.au3 или моей мыши Razer, перехват срабатывает, но в играх начинаются чудеса, курсор становится практически неуправляемый.
Потому что в играх свой Hook на мышь, который перекрывает твой (из MouseOnEvent.au3). Отсюда и чудеса...
 
Верх