Что нового

Мышь, клавиатура MouseOnEvent - Обработка событии мышки

Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
В результате мы получаем безтормозной хук
Да, но как быть с возможностью блокировать событие? Ведь для блокировки на данный момент я использую возврат 1 или 0 вместо _WinAPI_CallNextHookEx.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
Как вариант можно через _WinAPI_CreatеString(), _WinAPI_GetString() и _WinAPI_FreeMemory(). Весь остальной код менять не нужно. В результате мы получаем безтормозной хук, т.к. PostMessage() в отличии от SendMessage() не ждет завершения выполнения обработчика.
Я так понимаю что для _WinAPI_GetString нужно использовать _WinAPI_SetMessageExtraInfo, но оно не работает с PostMessage, т.к функция _WinAPI_IsMemory возвращает False.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Не нужно никаких "ExtraInfo". Создаешь в памяти строку и получаешь хэндл:

Код:
$hFunc = _WinAPI_CreateString("UserFunctionName")


Передаешь хэндл посредством "wParam":

Код:
_WinAPI_PostMessage($hMyWnd, $WM_MYMSG, $hFunc, Null)


В обработчике WM_MYMSG делаешь следующее:

Код:
$sFunc = _WinAPI_GetString($wParam)
_WinAPI_FreeMemory($wParam) ; !!!
Call($sFunc, ...)


P.S

Код:
$hMyWnd = GUICreate("")
$WM_MYMSG = _WinAPI_RegisterWindowMessage("{1A7BEE00-00C8-4692-BA2B-13EA8B3AA6A1}")
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied
А как быть если кроме имени функции, мне нужно ещё и пользовательский параметр передать, можно как то массив в памяти передать?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR,
А если передавать индекс в массиве, а не строку с именем функции?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Если возможно, то да, проще передать индекс.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Обновление:

v2.1 [12.08.2015]
* Теперь если $iBlockDefProc = 0 (или при использовании _MouseSetOnEvent_RI), пользовательская функция $sFuncName вызывается посредством PostMessage для предотвращения проблем с задержкой хука (или WM_* сообщений).
* Косметические изменения в коде.
* Обновление документации.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR,
ИМХО, если в _WinAPI_PostMessage() передавать индекс в массивах $a__MSOE_Events_RI и $a__MSOE_Events не строкой, а числом (например, для $a__MSOE_Events_RI со знаком минус, а для $a__MSOE_Events со знаком плюс, чтобы их можно было различать), то можно упростить код и не использовать функции _WinAPI_CreateString(), _WinAPI_GetString() и _WinAPI_FreeMemory().

И еще. Если поменять в MouseOnEvent.au3 файлы #include на
Код:
#include-once
#include <WinAPIEx.au3>
#include <APIConstants.au3>
;~ #include <WinAPIGdi.au3>
;~ #include <WinAPIMisc.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <Timers.au3>
то Ваша UDF прекрасно работает и в версиях AutoIt 3.3.6.1 - 3.3.8.1

PS
Все это я проверил - работает.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Обновление...

v2.2 [13.08.2015]
* Снова поддерживается AutoIt 3.3.6.1 - 3.3.8.1.
* Улучшение в коде и косметические изменения.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Обновление...

v2.3 [04.11.2015]
* Добавлены пользовательские константы $MOE_RUNDEFPROC и $MOE_BLOCKDEFPROC, для возврата значения в функции события.
* Исправлена проблема с падением скрипта при изменении массива событии.
* Исправлена проблема с нагрузкой на ЦП вызываемая неправильным использованием timer kill.
* Обновлена документация.
 

vovsla

Осваивающий
Сообщения
607
Репутация
36
Autoit 3.3.10.2
Если блокировать одиночное нажатие кнопки мыши, а потом разблокировать только одиночное нажатие, то DBLCLK остается заблокированным.

Код:
#include <MouseOnEvent.au3>

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


;~ _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event")
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_MousePrimaryDown_Event", 0, 1)
;~ _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, Default, 0, 1)
ConsoleWrite('block'&@CRLF)
Sleep(5000)
ToolTip('')
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
;~ _MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT)
ConsoleWrite('unblock'&@CRLF)


While 1
	Sleep(100)
WEnd



Func _MousePrimaryDown_Event()
	ToolTip("Primary Mouse Button Down Blocked")
EndFunc


Func _Quit()
	Exit
EndFunc



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

Полностью блокирует мышку, но если во время блокирования мышки активно ей пользоваться - двигать и нажимать кнопки, то после разблокировки она сильно тормозит какое-то время

Код:
#include <MouseOnEvent.au3>

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

_MouseSetOnEvent($MOUSE_MOVE_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_Mouse_Event", 0, 1)
	_MouseSetOnEvent($MOUSE_PRIMARYUP_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "_Mouse_Event", 0, 1)
	_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_SECONDARYDBLCLK_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT, "_Mouse_Event", 0, 1)
	_MouseSetOnEvent($MOUSE_WHEELUP_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_WHEELDBLCLK_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_WHEELSCROLL_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_Mouse_Event", 0, 1)
	_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_XBUTTONDOWN_EVENT, "_Mouse_Event", 0, 1)
	_MouseSetOnEvent($MOUSE_XBUTTONUP_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_XBUTTONDBLCLK_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_XBUTTON2DOWN_EVENT, "_Mouse_Event", 0, 1)
	_MouseSetOnEvent($MOUSE_XBUTTON2UP_EVENT, "_Mouse_Event", 0, 1)
_MouseSetOnEvent($MOUSE_XBUTTON2DBLCLK_EVENT, "_Mouse_Event", 0, 1)


Sleep(10000)


_MouseSetOnEvent($MOUSE_MOVE_EVENT)
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_PRIMARYUP_EVENT)
_MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT)
_MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT)
_MouseSetOnEvent($MOUSE_SECONDARYDBLCLK_EVENT)
_MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_WHEELUP_EVENT)
_MouseSetOnEvent($MOUSE_WHEELDBLCLK_EVENT)
_MouseSetOnEvent($MOUSE_WHEELSCROLL_EVENT)
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT)
_MouseSetOnEvent($MOUSE_XBUTTONDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_XBUTTONUP_EVENT)
_MouseSetOnEvent($MOUSE_XBUTTONDBLCLK_EVENT)
_MouseSetOnEvent($MOUSE_XBUTTON2DOWN_EVENT)
	_MouseSetOnEvent($MOUSE_XBUTTON2UP_EVENT)
_MouseSetOnEvent($MOUSE_XBUTTON2DBLCLK_EVENT)


While 1
	Sleep(100)
WEnd



Func _Mouse_Event()
;~ 	ToolTip('Мышка заблокирована')
EndFunc


Func _Quit()
	Exit
EndFunc
 

Aleksandr Prilutskiy

Знающий
Сообщения
29
Репутация
9
Хочу чтобы при нажатии на среднюю клавишу мыши проигрывался звук.
Работает, но 1 раз... Чтобы сработало 2й раз приходится выходить из программы.

Код:
#include "MouseOnEvent.au3"
HotKeySet("{ESC}", "_Quit")
_MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT, "_DOWN_EVENT")

While 1
 Sleep(100)
WEnd

Func _DOWN_EVENT()
 SoundPlay("alarm.wav", 1)
EndFunc

Func _Quit()
 Exit
EndFunc


версия MouseOnEvent.au3 2.3

Может нужно как то сбрасывать события мыши или отправлять их системному обработчику?
 

Malderin

Новичок
Сообщения
68
Репутация
1
На рабочем ПК, где стоит WinXP все работает прекрасно, но вот на домашнем ПК, где стоит Win7 x64 Pro та же проблема что и у Aleksandr Prilutskiy. 1-2 раза скрипт отрабатывает, потом сколько не нажимай на забитую в скрипт клавишу мышки, реакции никакой. Помогает только перезапуск скрипта. С _Ispressed таких проблем не наблюдается, но там нет возможности забить функции на дополнительные кнопки мыши. В общем непонятно что тут не так и почему обработка нажатий так внезапно прекращается.
 

reset86

Новичок
Сообщения
47
Репутация
0
Win 10, работает некорректно, курсор, после разблокировки мыши, ведет себя как пьяный. Я так понял, проблема в самом хуке _WinAPI_SetWindowsHookEx.

Вариант 1:
Код:
#include <MouseOnEvent.au3>
#include <Misc.au3>
Global $bDown = False, $bUp = True, $IsPressed

While 1
$IsPressed = _IsPressed("11")
If $IsPressed And Not $bDown Then
$bDown = True
$bUp = False
_MouseBlockLeftNagat()

ElseIf Not $IsPressed And Not $bUp Then
$bDown = False
$bUp = True
_MouseBlockLeftOtgat()

EndIf

Sleep(10) ; Любая задержка в цикле, приводит к пьяной мыши, после нескольких нажатий.
WEnd

Func _MouseBlockLeftNagat()
_MouseSetOnEvent($MOUSE_WHEELSCROLL_EVENT, "__fake", 0, 1)
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "__fake", 0, 1)
ConsoleWrite ('1') ; нажато
EndFunc

Func _MouseBlockLeftOtgat()
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
_MouseSetOnEvent($MOUSE_WHEELSCROLL_EVENT)
ConsoleWrite ('0') ; отжато
EndFunc
Вариант 2:
Код:
#include <MouseOnEvent.au3>
#include <Misc.au3>
Global $bDown = False, $bUp = True, $IsPressed, $MouseEventZ = False, $MouseEventX = True

While 1
$IsPressed = _IsPressed("11")
If $IsPressed And Not $bDown Then
$bDown = True
$bUp = False

If Not $MouseEventZ Then
$MouseEventZ = True
$MouseEventX = False
_MouseBlockLeftNagat()
EndIf

ElseIf Not $IsPressed And Not $bUp Then
$bDown = False
$bUp = True

If Not $MouseEventX Then
$MouseEventZ = False
$MouseEventX = True
_MouseBlockLeftOtgat()
EndIf
EndIf

Sleep(10) ; Любая задержка в цикле, приводит к пьяной мыши, после нескольких нажатий.
WEnd

Func _MouseBlockLeftNagat()
_MouseSetOnEvent($MOUSE_WHEELSCROLL_EVENT, "__fake", 0, 1)
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "__fake", 0, 1)
ConsoleWrite ('1') ; нажато
EndFunc

Func _MouseBlockLeftOtgat()
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
_MouseSetOnEvent($MOUSE_WHEELSCROLL_EVENT)
ConsoleWrite ('0') ; отжато
EndFunc
Вариант 3 (не в цикле)
Код:
#include <MouseOnEvent.au3>

_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "__fake", 0, 1)
ConsoleWrite ('1')

Sleep(3000)

_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
ConsoleWrite ('0')

While 1
Sleep(100)
WEnd

Очень жаль, но проблему решить с этой UDF так и не смог. Приходится использовать _IsPressed('01'), при нажатии, под курсором создается невидимый GUI по верх окна, тем самым блокируется нажатие мыши, это криво и не правильно, хотелось бы использовать все таки эту UDF. BlockInputEx.au3, работает с мышью еще хуже (с клавиатурой работает идеально).

Невидимый GUI под курсором в момент нажатия.
Код:
#include <WindowsConstants.au3>
#include <Misc.au3>
Global $bDown1 = False, $bUp1 = True, $IsPressed1, $IsPressed2, $Blokxz

While 1
$IsPressed1 = _IsPressed("11")
$IsPressed2 = _IsPressed("01")

If $IsPressed1 And $IsPressed2 And Not $bDown1 Then
$bDown1 = True
$bUp1 = False
_BlockkX()
ConsoleWrite('1')

ElseIf Not $IsPressed2 And Not $bUp1 Then
$bDown1 = False
$bUp1 = True
ConsoleWrite('0')
GUIDelete($Blokxz)
EndIf

If _IsPressed("10") Then ; Выход Shift
Exit
EndIf
Sleep(10)
WEnd

Func _BlockkX()
$aPos = MouseGetPos()
;~ $Blokxz = GUICreate("", 20, 20, $aPos[0]-10, $aPos[1]-10, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) ; Прозрачный GUI
$Blokxz = GUICreate("", 20, 20, $aPos[0]-10, $aPos[1]-10, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
GUISetState()
EndFunc
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
reset86 [?]
Win 10, работает некорректно, курсор, после разблокировки мыши, ведет себя как пьяный
При чём тут разблокировка, эта библиотека не предназначена для блокировки чего либо (хотя и имеет такую возможность).

проблему решить с этой UDF так и не смог
В чём она заключается, что ты пытаешься сделать?

У меня с выше представленным скриптом курсор нормально работает (Win 10, AutoIt 3.3.14.2).
 

musicstashall

Знающий
Сообщения
322
Репутация
7
Подтверждаю, на x64, при срабатывании любого события мыши, происходит падение скрипта.

Win 10 x64
 

rpgeha

Новичок
Сообщения
10
Репутация
0
Идея классная! Но реализовано :whistle: крайне не стабильно ведет себя :'(
есть у кого-то на примете, что-то подобное, но стабильное, чтобы можно было ловить события нажатий мыши?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Обновление:

v2.4 [15.03.2020]
* Исправлена проблема с падением скрипта при запуске из под x64 скрипта. Спасибо LarsJ (Gary Frost?).
* Добавлена функция _MouseSetOnEvent_SetDblClckSpeed для установки скорости двойного нажатия.
 
Верх