1 (изменено: xGen, 2011-12-24 18:05:59)

Тема: AHK: MouseMove -> Wheel

Являюсь обладателем планшета под Win7 со встроенной оптической мышкой в виде квадратного окошка по которому нужно проводить пальцем (оптический трек).

Имеется желание использовать эту мышь в двух режимах:
1. обычная мышь
2. колесо прокрутки мыши (или клавиатурные UP DOWN)
Режим меняется определенной клавишей.

Код набросал, но есть баги:
1. Иногда вообще не двигается с места
2. двигается как нервная, т.е. не хватает плавности

   SetBatchLines, -1
   SetMouseDelay, -1
   CoordMode, Mouse
   OnExit, Exit

   hHook := DllCall("SetWindowsHookEx"
      , Int, WH_MOUSE_LL := 14
      , Int, RegisterCallback("LowLevelMouseProc", "Fast")
      , UInt, DllCall("GetModuleHandle", UInt, 0)
      , UInt, 0)
   Return

Exit:
   DllCall("UnhookWindowsHookEx", UInt, hHook)
   ExitApp
   
Esc:: ExitApp

SC127::
zzz := zzz ? 0 : 1
y_prev := ""
return

LowLevelMouseProc(nCode, wParam, lParam)
{
   global zzz
   global y_prev ;static y_prev

   if (nCode < 0 || wParam != 0x200)   ; WM_MOUSEMOVE = 0x200
      Return DllCall("CallNextHookEx", UInt, 0, Int, nCode, UInt, wParam, UInt, lParam)

   y := NumGet(lParam+0, 4)
   
   y_prev := y_prev = "" ? y : y_prev

   if (zzz = 1)
   {   
	if (y > y_prev)
	{
		Send {Up}
	}
	Else
		Send {Down}
	Return 1
   }
   else Return DllCall("CallNextHookEx", UInt, 0, Int, nCode, UInt, wParam, UInt, lParam)
}

Прошу помощи в доработке скрипта.
Не въеду как добавить плавности, посему click WheelUp не использовал

2

Re: AHK: MouseMove -> Wheel

SetBatchLines, -1
SetKeyDelay, 175
OnExit, Exit
hHook:=DllCall("SetWindowsHookEx", "Int", 0xE ; WH_MOUSE_LL
     , "Int", RegisterCallback("LowLevelMouseProc", "Fast")
     , "UInt", DllCall("GetModuleHandle", "UInt", 0)
     , "UInt", 0)
Return

Esc::ExitApp
Space::zzz:=!zzz, y_prev:=""

Label:
   If (y>y_prev)
      Send, {Down}
;      Click, WD
   Else If (y<y_prev)
      Send, {Up}
;      Click, WU
   Return

Exit:
   DllCall("UnhookWindowsHookEx", "UInt", hHook)
   ExitApp

LowLevelMouseProc(nCode, wParam, lParam)
{
   global
   If (nCode<0 || wParam!=0x200) ; WM_MOUSEMOVE
      Return, DllCall("CallNextHookEx", "UInt", 0
                                      , "Int", nCode
                                      , "UInt", wParam
                                      , "UInt", lParam)
   Else If zzz
   {
      y:=NumGet(lParam+4) , y_prev:=y_prev="" ? y:y_prev
      SetTimer, Label, -0
      Return, 1
   }
   Else
      Return, DllCall("CallNextHookEx", "UInt", 0
                                      , "Int", nCode
                                      , "UInt", wParam
                                      , "UInt", lParam)
}

3

Re: AHK: MouseMove -> Wheel

Огромное спасибо за помощь.

...но пришлось немного изменить скрипт, т.к., по не понятным для меня причинам, при серии движение-остановка мышью страница продолжала двигаться дальше и остановить ее не представлялось возможным.
От таймера я отказался из-за по-дергивания. Использовать Click, WD - не возможно - (иногда) происходит слишком быстрое перемещение страницы


SetBatchLines, -1
;SetKeyDelay, 175
OnExit, Exit
hHook:=DllCall("SetWindowsHookEx", "Int", 0xE ; WH_MOUSE_LL
     , "Int", RegisterCallback("LowLevelMouseProc", "Fast")
     , "UInt", DllCall("GetModuleHandle", "UInt", 0)
     , "UInt", 0)
Return
 
Esc::ExitApp
SC127::zzz:=!zzz, y_prev:=""

Exit:
   DllCall("UnhookWindowsHookEx", "UInt", hHook)
   ExitApp
 
LowLevelMouseProc(nCode, wParam, lParam)
{
   global
   If (nCode<0 || wParam!=0x200) ; WM_MOUSEMOVE
      Return, DllCall("CallNextHookEx", "UInt", 0
                                      , "Int", nCode
                                      , "UInt", wParam
                                      , "UInt", lParam)
   Else If zzz
   {
      y:=NumGet(lParam+4) , y_prev:=y_prev="" ? y:y_prev

      If (y>y_prev)
        Send, {Up}
        ;Click, WU
      Else If (y<y_prev)
        Send, {Down}
        ;Click, WD

      Return, 1
   }
   Else
      Return, DllCall("CallNextHookEx", "UInt", 0
                                      , "Int", nCode
                                      , "UInt", wParam
                                      , "UInt", lParam)
}

4

Re: AHK: MouseMove -> Wheel

xGen пишет:

От таймера я отказался из-за по-дергивания.

Без таймера присутствует эффект кинетики и ещё заметил, что если клавишу-переключатель нажать когда курсор в движении, то дальнейшие действия происходят не по сценарию.

...
   If (y>y_prev)
      Send, {Down}
;      Click, WD
   Else If (y<y_prev)
      Send, {Up}
;      Click, WU
...

Else If вместо просто Else в данном случае убирает подёргивания при медленном движении мышью.

5

Re: AHK: MouseMove -> Wheel

Постраничное перелистывание: 1 движение мышью (в целом) - одноперелистывание

SetBatchLines, -1
;SetKeyDelay, 175
OnExit, Exit
hHook:=DllCall("SetWindowsHookEx", "Int", 0xE ; WH_MOUSE_LL
     , "Int", RegisterCallback("LowLevelMouseProc", "Fast")
     , "UInt", DllCall("GetModuleHandle", "UInt", 0)
     , "UInt", 0)
Return
 
Esc::ExitApp
SC127::zzz:=!zzz, y_prev:="", PrevTime:=0

Exit:
   DllCall("UnhookWindowsHookEx", "UInt", hHook)
   ExitApp
 
LowLevelMouseProc(nCode, wParam, lParam)
{
   global

   If (nCode<0 || wParam!=0x200) ; WM_MOUSEMOVE
      Return, DllCall("CallNextHookEx", "UInt", 0
                                      , "Int", nCode
                                      , "UInt", wParam
                                      , "UInt", lParam)
   Else If zzz
   {
     Time := NumGet(lParam+0, 16)
     ;InactivityTime := Time - PrevTime
     y:=NumGet(lParam+4) , y_prev:=y_prev="" ? y:y_prev
     if Time - PrevTime > 600
     {
       If (y>y_prev)
         Send, {PgUp}
         ;Click, WU
       Else If (y<y_prev)
         Send, {PgDn}
         ;Click, WD
       PrevTime := Time
     }
     Return, 1
   }
   Else
      Return, DllCall("CallNextHookEx", "UInt", 0
                                      , "Int", nCode
                                      , "UInt", wParam
                                      , "UInt", lParam)
}