<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Установка хуков на события мыши и клавиатуры]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=6350</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=6350&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Установка хуков на события мыши и клавиатуры».]]></description>
		<lastBuildDate>Wed, 13 Jun 2018 19:15:26 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Установка хуков на события мыши и клавиатуры]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=125971#p125971</link>
			<description><![CDATA[<p>Обновлённый хук на события мыши.<br /></p><div class="codebox"><pre><code>#Persistent
MouseHook.Set()
; чтобы удалить
; MouseHook.Del()

class MouseHook
{
   Set()  {
      if !this.hook  {
         this.hook := this.SetMouseHook()
         OnExit( this.OnExit := ObjBindMethod(this, &quot;Del&quot;) )
      }
   }
   
   Del()  {
      if this.hook  {
         this.SetMouseHook(this.hook)
         this.hook := &quot;&quot;
         OnExit(this.OnExit, 0)
      }
   }
   
   SetMouseHook(hHook := &quot;&quot;)  {
      if hHook
         DllCall(&quot;UnhookWindowsHookEx&quot;, Ptr, hHook)
      else
         Return hHook := DllCall(&quot;SetWindowsHookEx&quot;, Int, WH_MOUSE_LL := 14
                                                   , Ptr, RegisterCallback(&quot;LowLevelMouseProc&quot;, &quot;Fast&quot;)
                                                   , Ptr, DllCall(&quot;GetModuleHandle&quot;, UInt, 0, Ptr)
                                                   , UInt, 0, Ptr)
   }
}

LowLevelMouseProc(nCode, wParam, lParam)  {
   static oMem := [], lpData, size := VarSetCapacity(lpData, 16 + A_PtrSize*2, 0)

   DllCall(&quot;RtlMoveMemory&quot;, Ptr, &amp;lpData, Ptr, lParam, Ptr, size)
   oMem.Push([wParam, &amp;lpData])
   timer := Func(&quot;EventHandling&quot;).Bind(oMem)  ; во избежание фризов мыши обработка событий должна
   SetTimer, % timer, -10                     ; происходить обязательно по таймеру, а не в теле этой функции
   Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
}

EventHandling(oMem)  {
   static oMsg := { 0x200: &quot;WM_MOUSEMOVE&quot;
                  , 0x201: &quot;WM_LBUTTONDOWN&quot;, 0x202: &quot;WM_LBUTTONUP&quot;
                  , 0x204: &quot;WM_RBUTTONDOWN&quot;, 0x205: &quot;WM_RBUTTONUP&quot;
                  , 0x207: &quot;WM_MBUTTONDOWN&quot;, 0x208: &quot;WM_MBUTTONUP&quot;
                  , 0x20B: &quot;WM_XBUTTONDOWN&quot;, 0x20C: &quot;WM_XBUTTONUP&quot;
                  , 0x20A: &quot;WM_MOUSEWHEEL&quot; , 0x20E: &quot;WM_MOUSEHWHEEL&quot; }
                
        , oMouseData := { 0: &quot;0&quot;, 1: &quot;XBUTTON1&quot;, 2: &quot;XBUTTON2&quot;
                        , 120: &quot;WHEEL_DELTA forward&quot;, -120: &quot;WHEEL_DELTA backward&quot; }
                        
   prevTTCoordMode := A_CoordModeToolTip
   CoordMode, ToolTip
   while event := oMem.RemoveAt(1)  {
      msg       := oMsg[ event[1] ]
      mouse_x   := NumGet(event[2] + 0, &quot;Int&quot;)
      mouse_y   := NumGet(event[2] + 4, &quot;Int&quot;)
      ext       := NumGet(event[2] + 10, &quot;Short&quot;)
      flags     := NumGet(event[2] + 12, &quot;UInt&quot;)
      time      := NumGet(event[2] + 16, &quot;UInt&quot;)
      INJECTED  := flags &amp; 1
      LOWER_IL_INJECTED := flags &gt;&gt; 1
      mouseData := oMouseData[ext]
      
      ToolTip % &quot;Msg: &quot;  . A_Tab . A_Tab . msg               . &quot;`n&quot;
              . &quot;MouseData: &quot;    . A_Tab . mouseData         . &quot;`n&quot;
              . &quot;MouseX: &quot;       . A_Tab . mouse_x           . &quot;`n&quot;
              . &quot;MouseY: &quot;       . A_Tab . mouse_y           . &quot;`n&quot;
              . &quot;INJECTED: &quot;     . A_Tab . INJECTED          . &quot;`n&quot;
              . &quot;LIL_INJECTED: &quot; . A_Tab . LOWER_IL_INJECTED . &quot;`n&quot;
              . &quot;Time: &quot; . A_Tab . A_Tab . time, 0, 0, 20
   }
   CoordMode, ToolTip, % prevTTCoordMode
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Wed, 13 Jun 2018 19:15:26 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=125971#p125971</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Установка хуков на события мыши и клавиатуры]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=117565#p117565</link>
			<description><![CDATA[<p>Обновлённый код для клавиатурного хука. Добавлена технология, предложенная коллегой <strong>serzh82saratov</strong>, для сохранения и обработки всех событий без потерь в случае поступления их большого количества в короткий промежуток времени.<br /></p><div class="codebox"><pre><code>CoordMode, ToolTip
hHookKeybd := DllCall(&quot;SetWindowsHookEx&quot;
   , Int, WH_KEYBOARD_LL := 13
   , Ptr, RegisterCallback(&quot;LowLevelKeyboardProc&quot;, &quot;Fast&quot;)
   , Ptr, DllCall(&quot;GetModuleHandle&quot;, UInt, 0, Ptr)
   , UInt, 0, Ptr)
OnExit( Func(&quot;Exit&quot;).Bind(hHookKeybd) )
Return

Esc::ExitApp

Exit(hHookKeybd)  {
   DllCall(&quot;UnhookWindowsHookEx&quot;, Ptr, hHookKeybd)
}

LowLevelKeyboardProc(nCode, wParam, lParam)  {
   static oMem := [], lpData, size := VarSetCapacity(lpData, 16, 0)

   DllCall(&quot;RtlMoveMemory&quot;, Ptr, &amp;lpData, Ptr, lParam, Ptr, size)
   oMem.Push([wParam, &amp;lpData])
   timer := Func(&quot;EventHandling&quot;).Bind(oMem)  ; во избежание фризов клавиатуры обработка событий должна
   SetTimer, % timer, -10                     ; происходить обязательно по таймеру, а не в теле этой функции
   Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
}

EventHandling(oMem)  {
   static oMsg := {0x100: &quot;WM_KEYDOWN&quot;, 0x101: &quot;WM_KEYUP&quot;, 0x104: &quot;WM_SYSKEYDOWN&quot;, 0x105: &quot;WM_SYSKEYUP&quot;}
        , oMembers := [&quot;vk&quot;, &quot;sc&quot;, &quot;flags&quot;, &quot;time&quot;]
        , oFlagOffsets := {LLKHF_EXTENDED: 0, LLKHF_LOWER_IL_INJECTED: 1, LLKHF_INJECTED: 4, LLKHF_ALTDOWN: 5, LLKHF_UP: 7}

   while (oMem[1] != &quot;&quot;)   {
      key := oMem.RemoveAt(1)
      wp := key[1], lp := key[2]

      msg := wp
      for k, v in oMembers
         %v% := NumGet(lp + (k - 1)*4, &quot;UInt&quot;)
      
      for k, v in oFlagOffsets
         %k% := (flags &gt;&gt; v) &amp; 1
      
      sc |= LLKHF_EXTENDED &lt;&lt; 8
      
; текстовые значения в oMembers и названия ключей в oFlagOffsets являются
; названиями переменных, в которых теперь находятся соответствующие значения:
      ToolTip % &quot;Message = &quot;   . oMsg[msg]           . &quot;`n&quot;
              . &quot;vkCode = &quot;    . Format(&quot;{:#x}&quot;, vk) . &quot;`n&quot;
              . &quot;scCode = &quot;    . Format(&quot;{:#x}&quot;, sc) . &quot;`n&quot;
              . &quot;pressed = &quot;   . !LLKHF_UP           . &quot;`n&quot;
              . &quot;Time = &quot;      . time                . &quot;`n&quot;
              . &quot;Injected = &quot;  . LLKHF_INJECTED      . &quot;`n&quot;
              . &quot;Lower_IL_Injected = &quot; . LLKHF_LOWER_IL_INJECTED, 0, 0
   } 
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Mon, 24 Jul 2017 22:44:31 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=117565#p117565</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Установка хуков на события мыши и клавиатуры]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=52804#p52804</link>
			<description><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/library/ms644959%28VS.85%29.aspx">Хук</a> — это механизм, с помощью которого приложения могут перехватывать события — сообщения, действия мыши и нажатия клавиш. Функция, которая перехватывает определённые типы событий, называется хук-процедура (hook procedure). Хук-процедура может производить различные действия над каждым получаемым событием, модифицировать или исключать его. MSDN <a href="http://msdn.microsoft.com/en-us/library/ms644959%28VS.85%29.aspx#procedures">пишет</a>, что если приложение устанавливает хук для отслеживания событий другого приложения, хук-процедура должна находиться в отдельной dll.</p><p>Однако <a href="http://www.autohotkey.com/forum/topic19367-45.html#p127490">замечено</a>, что для отслеживания событий мыши и клавиатуры можно обойтись без написания dll и расположить хук-процедуру непосредственно в теле скрипта.</p><p>Клавиатурный хук:<br /></p><div class="codebox"><pre><code>OnExit, Exit
hHookKeybd := DllCall(&quot;SetWindowsHookEx&quot;
   , Int, WH_KEYBOARD_LL := 13
   , Ptr, RegisterCallback(&quot;LowLevelKeyboardProc&quot;, &quot;Fast&quot;)
   , Ptr, DllCall(&quot;GetModuleHandle&quot;, UInt, 0, Ptr)
   , UInt, 0, Ptr)
Return

Exit:
   DllCall(&quot;UnhookWindowsHookEx&quot;, Ptr, hHookKeybd)
   ExitApp

LowLevelKeyboardProc(nCode, wParam, lParam)
{
   static msg, vk, sc, time
      , oMsg := {0x100: &quot;WM_KEYDOWN&quot;, 0x101: &quot;WM_KEYUP&quot;, 0x104: &quot;WM_SYSKEYDOWN&quot;, 0x105: &quot;WM_SYSKEYUP&quot;}
   
   SetFormat, IntegerFast, H
   msg := wParam . &quot;&quot;                       ; добавляем &quot;&quot;, чтобы шестнадцатеричное число интерпретировалось, 
   vk  := NumGet(lParam + 0, &quot;UInt&quot;) . &quot;&quot;   ; как строка, и не превратилось в десятичное после смены формата
   ext := NumGet(lParam + 8, &quot;UInt&quot;) &amp; 1
   sc  := NumGet(lParam + 4, &quot;UInt&quot;) | ext &lt;&lt; 8 . &quot;&quot;
   
   SetFormat, IntegerFast, D
   time := NumGet(lParam + 12, &quot;UInt&quot;)
   
   SetTimer, EventHandling, -10   ; обработку событий &quot;повесим&quot; на таймер, чтобы не создавать помех в работе клавиатуры
   Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
   
EventHandling:
   TrayTip,, % &quot;Message = &quot;  . oMsg[msg]
             . &quot;`nvkCode = &quot; . vk
             . &quot;`nscCode = &quot; . sc
             . &quot;`nTime = &quot;   . time
   Return
}

Esc::ExitApp</code></pre></div><p>Хук на события мыши:<br /></p><div class="codebox"><pre><code>OnExit, Exit
hHookMouse := DllCall(&quot;SetWindowsHookEx&quot;
   , Int, WH_MOUSE_LL := 14
   , Ptr, RegisterCallback(&quot;LowLevelMouseProc&quot;, &quot;Fast&quot;)
   , Ptr, DllCall(&quot;GetModuleHandle&quot;, UInt, 0, Ptr)
   , UInt, 0, Ptr)
 Return

Exit:
    DllCall(&quot;UnhookWindowsHookEx&quot;, Ptr, hHookMouse)
    ExitApp

LowLevelMouseProc(nCode, wParam, lParam)
{
   static msg, mouse_x, mouse_y, ext, time
      , oMsg := { 0x200: &quot;WM_MOUSEMOVE&quot;
                , 0x201: &quot;WM_LBUTTONDOWN&quot;, 0x202: &quot;WM_LBUTTONUP&quot;
                , 0x204: &quot;WM_RBUTTONDOWN&quot;, 0x205: &quot;WM_RBUTTONUP&quot;
                , 0x207: &quot;WM_MBUTTONDOWN&quot;, 0x208: &quot;WM_MBUTTONUP&quot;
                , 0x20B: &quot;WM_XBUTTONDOWN&quot;, 0x20C: &quot;WM_XBUTTONUP&quot;
                , 0x20A: &quot;WM_MOUSEWHEEL&quot; , 0x20E: &quot;WM_MOUSEHWHEEL&quot; }
                
      , oMouseData := { 0: &quot;0&quot;, 1: &quot;XBUTTON1&quot;, 2: &quot;XBUTTON2&quot;
                      , 120: &quot;WHEEL_DELTA forward&quot;, -120: &quot;WHEEL_DELTA backward&quot; }

   msg := wParam
   mouse_x := NumGet(lParam + 0, &quot;Int&quot;)
   mouse_y := NumGet(lParam + 4, &quot;Int&quot;)
   ext     := NumGet(lParam + 10, &quot;Short&quot;)
   time    := NumGet(lParam + 16, &quot;UInt&quot;)
   
   SetTimer, EventHandling, -10
   Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)

EventHandling:
   ToolTip, % &quot;Message = &quot;     . oMsg[msg]
            . &quot;`nMouse_X = &quot;   . mouse_x
            . &quot;`nMouse_Y = &quot;   . mouse_y
            . &quot;`nMouseData = &quot; . oMouseData[ext]
            . &quot;`nTime = &quot;      . time
   Return
}

Esc::ExitApp</code></pre></div><p>В случае, если параметр <em>nCode</em> хук-процедуры меньше нуля, она обязательно должна возвращать значение, возвращаемое функцией <a href="http://msdn.microsoft.com/en-us/library/ms644974%28VS.85%29.aspx"><em>CallNextHookEx()</em></a>. В остальных случаях также возвращение данного значения желательно, иначе другие приложения, где установлен такой же хук, не будут получать событий, что может привести к некорректной их работе.</p><p>Примеры использования:<br /><a href="http://forum.script-coding.com/viewtopic.php?pid=52762#p52762">Полная блокировка событий мыши</a><br /><a href="http://forum.script-coding.com/viewtopic.php?pid=48604#p48604">Инверсия мыши по вертикали</a><br /><a href="http://forum.script-coding.com/viewtopic.php?id=5697">Определение символов, посылаемых с клавиатуры</a><br /><a href="http://forum.script-coding.com/viewtopic.php?id=5690">Определение виртуальных и скан-кодов клавиатуры</a></p><p>Информация:<br /><a href="http://msdn.microsoft.com/en-us/library/ms644990%28VS.85%29.aspx"><em>SetWindowsHookEx()</em></a><br /><a href="http://msdn.microsoft.com/en-us/library/ms644985%28VS.85%29.aspx"><em>LowLevelKeyboardProc()</em></a><br /><a href="http://msdn.microsoft.com/en-us/library/ms644986%28VS.85%29.aspx"><em>LowLevelMouseProc()</em></a></p><p><a href="http://forum.script-coding.com/viewtopic.php?id=6339">Тема для обсуждения.</a></p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Sat, 22 Oct 2011 19:32:01 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=52804#p52804</guid>
		</item>
	</channel>
</rss>
