1 (изменено: ypppu, 2010-11-26 01:03:00)

Тема: AHK: Назначить действие на движение мыши

Хотелось бы в некоторых программах (особенно, где управление камерой производится клавишами) задать движения мышки в качестве горячих клавиш.
Как это осуществить - ни разу не сталкивался. Наверно, для начала нужно перехватить события мышки. На сайте есть такая тема http://www.autohotkey.com/forum/viewtop … 490#127490, где представлен код

#Persistent
OnExit, Unhook

hHookKeybd := SetWindowsHookEx(WH_KEYBOARD_LL   := 13, RegisterCallback("Keyboard", "Fast"))
;hHookMouse := SetWindowsHookEx(WH_MOUSE_LL   := 14, RegisterCallback("MouseMove", "Fast"))
Return

Unhook:
UnhookWindowsHookEx(hHookKeybd)
;UnhookWindowsHookEx(hHookMouse)
ExitApp


Keyboard(nCode, wParam, lParam)
{
   Critical
   If !nCode
   OutputDebug, % wParam . "|" . " vkCode: " . NumGet(lParam+0, 0) . " scCode: " . NumGet(lParam+0, 4) . " Extended: " . NumGet(lParam+0, 8) & 1 . " Time: " . NumGet(lParam+0, 12)
   Return CallNextHookEx(nCode, wParam, lParam)
}

MouseMove(nCode, wParam, lParam)
{
   Critical
   If !nCode && (wParam = 0x200)
   OutputDebug, % " X: " . NumGet(lParam+0, 0, "int") . " Y: " . NumGet(lParam+0, 4, "int")
   Return CallNextHookEx(nCode, wParam, lParam)
}

SetWindowsHookEx(idHook, pfn)
{
   Return DllCall("SetWindowsHookEx", "int", idHook, "Uint", pfn, "Uint", DllCall("GetModuleHandle", "Uint", 0), "Uint", 0)
}

UnhookWindowsHookEx(hHook)
{
   Return DllCall("UnhookWindowsHookEx", "Uint", hHook)
}

CallNextHookEx(nCode, wParam, lParam, hHook = 0)
{
   Return DllCall("CallNextHookEx", "Uint", hHook, "int", nCode, "Uint", wParam, "Uint", lParam)
}

Просьба помочь разобраться с кодом. Выслушаю ваши соображения об этой теме.

2

Re: AHK: Назначить действие на движение мыши

Такой код устанавливает хук на события мыши:

   #Persistent
   OnExit, Exit
   hHookKeybd := DllCall("SetWindowsHookEx"
      , Int, WH_MOUSE_LL := 14
      , Int, RegisterCallback("LowLevelMouseProc", "Fast")
      , UInt, DllCall("GetModuleHandle", UInt, 0)
      , UInt, 0)
   Return

Exit:
   DllCall("UnhookWindowsHookEx", Uint, hHookKeybd)
   ExitApp

LowLevelMouseProc(nCode, wParam, lParam)
{
   ToolTip, % "Message = " . wParam
      . "`nMouse_X = " . NumGet(lParam+0, 0)
      . "`nMouse_Y = " . NumGet(lParam+0, 4)
      . "`nExtended = " . (NumGet(lParam+0, 8)&0xFFFF0000)>>16
      . "`nTime = " . NumGet(lParam+0, 16)
   Return DllCall("CallNextHookEx", UInt, 0, Int, nCode, UInt, wParam, UInt, lParam)
}

wParam может принимать значения, соответствующие WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_RBUTTONDOWN, или WM_RBUTTONUP. Установка хука означает, что перед системной обработкой этих событий будет выполнен код из функции LowLevelMouseProc(), в данном случае извлечение значений и показ ToolTip'а.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: teadrinker, 2010-11-27 02:22:24)

Re: AHK: Назначить действие на движение мыши

Только, чтобы назначить действия на движения мыши, это всё не нужно !
Вот такой скриптик у меня получился для жестов с зажатой правой кнопкой, если активен блокнот:

   Sensitivity = 20
   CoordMode, Mouse
   Return

Esc:: ExitApp

#IfWinActive, ahk_class Notepad
RButton::
   NewGesture = 1
   While GetKeyState("RButton", "P")
   {
      if NewGesture
      {
         MouseGetPos, StartX, StartY
         NewGesture =
      }

      MouseGetPos, X, Y
      DX := X - StartX, DY := Y - StartY
      
      if (Abs(DX) >= Sensitivity)
         Gesture := (DX > 0 ? "R" : "L"), NewGesture := 1
         
      if (Abs(DY) >= Sensitivity)
         Gesture := (DY > 0 ? "D" : "U"), NewGesture := 1
         
      if (NewGesture && Gesture != PrevGesture)
         Gestures .= Gesture, PrevGesture := Gesture
         
      Sleep, 10
   }
   if !Gestures
      Send, {RButton}
   else
      MsgBox, % Gestures   ; здесь назначить действие в зависимости от значения Gestures
   Gestures := Gesture := PrevGesture := ""
   Return

RButton Up::Return
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4

Re: AHK: Назначить действие на движение мыши

teadrinker пишет:

Только, чтобы назначить действия на движения мыши, это всё не нужно !
Вот такой скриптик у меня получился для жестов с зажатой правой кнопкой, если активен блокнот

А если курсор упрётся в край экрана? Программа не поймёт, что мышка всё ещё двигается?

5

Re: AHK: Назначить действие на движение мыши

На работе для автокада пользуюсь жестами мыши. Брал скрипт тут на форуме и модифицировал под себя. Ни разу не столкнулся с такой проблемой, что упирался мышью в край экрана. Для жеста требуется совсем мало места на экране.

6

Re: AHK: Назначить действие на движение мыши

Да, согласен с предыдущим оратором, чувствительность для одного жеста в скрипте всего 20 точек.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Назначить действие на движение мыши

Насколько я понял, оба скрипта не дают понять, какие команды исходят от мыши. Только косвенно (проверка координат курсора).

8

Re: AHK: Назначить действие на движение мыши

От мыши исходят не команды, а события: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_RBUTTONDOWN или WM_RBUTTONUP. Первый скрипт отлавливает именно их, причём до обработки их системой.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9 (изменено: ypppu, 2010-11-27 22:19:11)

Re: AHK: Назначить действие на движение мыши

События кнопок в принципе не интересуют, а вот событие WM_MOUSEMOVE не говорит о том, в какую сторону была перемещена мышь.

10

Re: AHK: Назначить действие на движение мыши

Так там же координаты можно извлечь!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Назначить действие на движение мыши

Ладно, с 3 раз не поняли, вопрос закрыт.

12

Re: AHK: Назначить действие на движение мыши

ypppu пишет:

с 3 раз не поняли

Ну, видно ума не хватило!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Назначить действие на движение мыши

ypppu пишет:

...А если курсор упрётся в край экрана? Программа не поймёт, что мышка всё ещё двигается?

На этот случай есть CursorUS

14 (изменено: andysss, 2011-05-06 17:49:17)

Re: AHK: Назначить действие на движение мыши

Подскажите как в этом коде с блокнотом посылать нажатия клавиш Right, Left, Up, Down чтобы нажимались эти клавиши?

Sensitivity = 20
   CoordMode, Mouse
   Return

Esc:: ExitApp

#IfWinActive, ahk_class Notepad
RButton::
   NewGesture = 1
   While GetKeyState("RButton", "P")
   {
      if NewGesture
      {
         MouseGetPos, StartX, StartY
         NewGesture =
      }

      MouseGetPos, X, Y
      DX := X - StartX, DY := Y - StartY
      
      if (Abs(DX) >= Sensitivity)
         Gesture := (DX > 0 ? "R" : "L"), NewGesture := 1
         
      if (Abs(DY) >= Sensitivity)
         Gesture := (DY > 0 ? "D" : "U"), NewGesture := 1
         
      if (NewGesture && Gesture != PrevGesture)
         Gestures .= Gesture, PrevGesture := Gesture
         
      Sleep, 10
   }
   if !Gestures
      Send, {RButton}
   else
      MsgBox, % Gestures   ; здесь назначить действие в зависимости от значения Gestures
   Gestures := Gesture := PrevGesture := ""
   Return

RButton Up::Return

15

Re: AHK: Назначить действие на движение мыши

andysss пишет:

Подскажите как...?

Sensitivity = 20
   CoordMode, Mouse
   Return
Esc:: ExitApp
#IfWinActive, ahk_class Notepad
RButton::
   NewGesture = 1
   While GetKeyState("RButton", "P")
   {
      if NewGesture
      {
         MouseGetPos, StartX, StartY
         NewGesture =
      }
      MouseGetPos, X, Y
      DX := X - StartX, DY := Y - StartY
      if (Abs(DX) >= Sensitivity)
         Gesture := (DX > 0 ? "Right" : "Left"), NewGesture := 1
      if (Abs(DY) >= Sensitivity)
         Gesture := (DY > 0 ? "Down" : "Up"), NewGesture := 1
      if (NewGesture && Gesture != PrevGesture)
         Gestures .= Gesture, PrevGesture := Gesture
      Sleep, 10
   }
   if !Gestures
      Send, {RButton}
   else
Send, {%Gestures%}
   Gestures := Gesture := PrevGesture := ""
   Return
RButton Up::Return

16

Re: AHK: Назначить действие на движение мыши

Или так:

Sensitivity = 20
CoordMode, Mouse
Return
Esc:: ExitApp
#IfWinActive, ahk_class Notepad
RButton::
   NewGesture = 1
   While GetKeyState("RButton", "P")
      {
         If NewGesture
         {
            MouseGetPos, StartX, StartY
            NewGesture =
         }
         MouseGetPos, X, Y
         DX := X - StartX, DY := Y - StartY
         If (Abs(DX) >= Sensitivity)
            Gesture := (DX > 0 ? "{Right}" : "{Left}"), NewGesture := 1
         If (Abs(DY) >= Sensitivity)
            Gesture := (DY > 0 ? "{Down}" : "{Up}"), NewGesture := 1
         If (NewGesture && Gesture != PrevGesture)
            Gestures .= Gesture, PrevGesture := Gesture
         Sleep, 10
      }
   If !Gestures
      Send, {RButton}
   Else
      Send, % Gestures
      Gestures := Gesture := PrevGesture := ""
Return
RButton Up::Return

Разници нет (кроме оформления).

17

Re: AHK: Назначить действие на движение мыши

Спасибо! Для вас это пару секунд, для меня тёмный лес, иногда с просветами))

18

Re: AHK: Назначить действие на движение мыши

OFF:2andysss: далеко, очень далеко не пару секунд.

19

Re: AHK: Назначить действие на движение мыши

Ещё нюанс, а можно чтобы постоянно шло нажатие до тех пор, пока не отожмётся RButton?

20

Re: AHK: Назначить действие на движение мыши

andysss пишет:

...а можно чтобы постоянно шло нажатие до тех пор, пока не отожмётся RButton?

Можно, но уже без варианта когда в хоткее есть функция посыла самой себя в статичном состоянии, хотя наверное можно и это исправить (я не имею ввиду ~ перед хоткеем).:

Sensitivity = 20
CoordMode, Mouse
Return
Esc:: ExitApp
#IfWinActive, ahk_class Notepad
RButton::
   NewGesture = 1
   Loop
      {
         If NewGesture
         {
            MouseGetPos, StartX, StartY
            NewGesture =
         }
         MouseGetPos, X, Y
         DX := X - StartX, DY := Y - StartY
         If (Abs(DX) >= Sensitivity)
            Gesture := (DX > 0 ? "{Right}" : "{Left}"), NewGesture := 1
         If (Abs(DY) >= Sensitivity)
            Gesture := (DY > 0 ? "{Down}" : "{Up}"), NewGesture := 1
         If (NewGesture && Gesture != PrevGesture)
            Gestures .= Gesture, PrevGesture := Gesture
         Sleep, 10
         Send, % Gestures
         Gestures := Gesture := PrevGesture := ""
         If GetKeyState("RButton", "P") = 0
            break
      }
Return
RButton Up::Return

21 (изменено: andysss, 2011-05-12 07:36:25)

Re: AHK: Назначить действие на движение мыши

Спасибо. Убавляешь sensitivity и тянешь мышь, вроде оно... Лучше бы было конечно при отпускании RButton.

22

Re: AHK: Назначить действие на движение мыши

Можно ли как-то сделать, чтобы

If (Abs(DX) >= Sensitivity)
            Gesture := (DX > 0 ? "{Right}" : "{Left}"), NewGesture := 1
         If (Abs(DY) >= Sensitivity)
            Gesture := (DY > 0 ? "{Down}" : "{Up}"), NewGesture := 1

Up, Down..... посылались как sendplay?

23

Re: AHK: Назначить действие на движение мыши

Заменить

Send, % Gestures

на

Sendplay, % Gestures

24

Re: AHK: Назначить действие на движение мыши

Спасибо

25

Re: AHK: Назначить действие на движение мыши

По теме.
Кажется всё проще, нужно отслеживать, насколько курсор сместился от центра. А чтобы он не доходил до края экрана, периодически возвращать его в центр.

26

Re: AHK: Назначить действие на движение мыши

На офф.форуме имеется тема Lex' Mouse Gestures by Lexicos.