Что нового

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

Автор
CreatoR

CreatoR

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

CreatoR

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 714
Не нужно никаких "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 605
Репутация
2 437
Yashied
А как быть если кроме имени функции, мне нужно ещё и пользовательский параметр передать, можно как то массив в памяти передать?
 

madmasles

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

Yashied

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

CreatoR

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

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

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 320
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 605
Репутация
2 437
Обновление...

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

CreatoR

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

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

vovsla

Осваивающий
Сообщения
553
Репутация
26
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

Новичок
Сообщения
60
Репутация
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 605
Репутация
2 437
reset86 [?]
Win 10, работает некорректно, курсор, после разблокировки мыши, ведет себя как пьяный
При чём тут разблокировка, эта библиотека не предназначена для блокировки чего либо (хотя и имеет такую возможность).

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

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

musicstashall

Новичок
Сообщения
277
Репутация
4
Подтверждаю, на x64, при срабатывании любого события мыши, происходит падение скрипта.

Win 10 x64
 

rpgeha

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

CreatoR

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

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