<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; АНК: Прокрутка окна под курсором мыши без активации окна]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=456</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=456&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «АНК: Прокрутка окна под курсором мыши без активации окна».]]></description>
		<lastBuildDate>Tue, 05 Nov 2013 05:49:47 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: АНК: Прокрутка окна под курсором мыши без активации окна]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=76927#p76927</link>
			<description><![CDATA[<p>Вариант кода из первого сообщения. В отличие от него также работает в AutoHotkey x64 (проверено) и должен работать (не проверено) при отрицательных значениях mX. Последнее возможно при расширении Рабочего стола на второй монитор, стоящий слева. Проверить нет возможности за отсутствием второго монитора.<br /></p><div class="codebox"><pre><code>WheelUp::
WheelDown::
    Critical
    If(A_ThisHotkey!=A_PriorHotkey || A_TimeSincePriorHotkey&gt;40) ; Определить скорость
        Scroll:= A_ThisHotkey=&quot;WheelUp&quot; ? 120&lt;&lt;16 : -120&lt;&lt;16     ; вращения колеса и
    Else                                                         ; задать скорость
        Scroll:= A_ThisHotkey=&quot;WheelUp&quot; ? 240&lt;&lt;16 : -240&lt;&lt;16     ; прокрутки.

    CoordMode, Mouse, Screen
    MouseGetPos, mX, mY
    mX &amp;= 0x00000000FFFFFFFF
    Point := mX | mY&lt;&lt;32
    WinID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int64&quot;, Point, &quot;ptr&quot;)   ; ID (handle) окна
    Point := mX | (mY-20)&lt;&lt;32                                  ; под мышью.
    NextID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int64&quot;, Point, &quot;ptr&quot;)
    mX &amp;= 0x0000FFFF
    SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %WinID%   ; 0x20A = WM_MOUSEWHEEL
    If (!ErrorLevel &amp;&amp; (WinID != NextID))
        SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %NextID%
Return</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Tue, 05 Nov 2013 05:49:47 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=76927#p76927</guid>
		</item>
		<item>
			<title><![CDATA[Re: АНК: Прокрутка окна под курсором мыши без активации окна]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=13015#p13015</link>
			<description><![CDATA[<p>Еще побаловался и нашел прокольчик в скрипте. Есть у меня маленькая любиная программулька VolumeControl - сидит в трее и. когда над ее иконкой крутишь колесо, - меняет громкость. Так вот, при запущеном скрипте - не работает.<br />Было у меня подозрение на закоменнтированные строчки кода в следующем скрипте, но не оправдалось.<br />Однако, скрипт без этих строчек работает так же как и с ними. Признаюсь, назначение их не понимаю. Посему к&nbsp; YMP, как автору кода, есть просьба дать пояснения.<br />В своей части кода я внес малые усовершенствования - ускорение меняется теперь нелинейно. И жить стало лучше, стало веселее. <br /></p><div class="codebox"><pre><code>WheelUp::
WheelDown::
  Critical
  Acceleration = 50 ;ускорение (НА мой вкус, хорошо от 30 до 100)

  Scroll :=  A_ThisHotkey=&quot;WheelUp&quot; ? +1 : -1
  Scroll &lt;&lt;= 30 - 4*ATan( A_TimeSincePriorHotkey/(1+Acceleration) )

  CoordMode, Mouse, Screen
  MouseGetPos, mX, mY
  WinID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int&quot;, mX, &quot;int&quot;, mY)      ; ID (handle) окна
;  NextID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int&quot;, mX, &quot;int&quot;, mY-20)  ; под мышью.

  SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %WinID%   ; 0x20A = WM_MOUSEWHEEL
;  If (!ErrorLevel &amp;&amp; (WinID != NextID))
;    SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %NextID%
Return</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (NikVasKo)]]></author>
			<pubDate>Mon, 04 Aug 2008 12:38:21 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=13015#p13015</guid>
		</item>
		<item>
			<title><![CDATA[Re: АНК: Прокрутка окна под курсором мыши без активации окна]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=13009#p13009</link>
			<description><![CDATA[<p>Попробовав настоящий скрипт, оченно возрадовался. Фантастически удобно. Спасибо всем сочинителям.<br />Денек побаловался и, кажется, сделал скрипт чуть лучше: теперь ускорение добавляется не скачком, а плавно&nbsp; растет вместе с раскруткой колеса (разгон примерно линейно зависит от скорости вращения). <br />Опробовал на десятке программ - везде хуже или лучше работает. Всем очень рекомендую. <br />В системных настройках мыши полезно установить минимальный шаг.<br /></p><div class="codebox"><pre><code>WheelUp::
WheelDown::
  Critical
  Sign :=  A_ThisHotkey=&quot;WheelUp&quot; ? 1 : -1
  Acceleration = 10 ;степень ускорения проматывания (от 0 до ...)
  Scroll := 1 + 10*( Acceleration / (A_TimeSincePriorHotkey + 1) ) ;добавляем ускорение
  Scroll *= Sign * 120 &lt;&lt; 16

  CoordMode, Mouse, Screen
  MouseGetPos, mX, mY
  WinID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int&quot;, mX, &quot;int&quot;, mY)      ; ID (handle) окна
  NextID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int&quot;, mX, &quot;int&quot;, mY-20)  ; под мышью.

  SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %WinID%   ; 0x20A = WM_MOUSEWHEEL
  If (!ErrorLevel &amp;&amp; (WinID != NextID))
    SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %NextID%
Return</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (NikVasKo)]]></author>
			<pubDate>Sun, 03 Aug 2008 18:51:57 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=13009#p13009</guid>
		</item>
		<item>
			<title><![CDATA[Re: АНК: Прокрутка окна под курсором мыши без активации окна]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=2803#p2803</link>
			<description><![CDATA[<p>Удалено, т.к. фактически повторяет код выше. Исправление перенесено туда.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Wed, 09 May 2007 03:21:35 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=2803#p2803</guid>
		</item>
		<item>
			<title><![CDATA[АНК: Прокрутка окна под курсором мыши без активации окна]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=2799#p2799</link>
			<description><![CDATA[<p>Я всегда считал, что прокручиваться должно то, что находится под курсором мыши. Но Windows считает иначе и прокручивает то, что имеет фокус ввода. Возьмём, например, окно с двумя панелями, типа Проводника или той же справки AutoHotkey. Прокручиваешь правую панель, потом переходишь в левую и хочешь прокрутить дерево, но не тут-то было - прокрутка идёт всё туда же, в правую часть. Сначала надо щёлкнуть по нужной панели, чтобы перебросить туда фокус. А когда переходишь обратно - опять та же морока. То же самое и с двумя (и более) отдельными окнами - сначала активируй, потом крути.</p><p>На форуме AutoHotkey я нашёл код, решающий эту проблему. Для желающих припасть к первоисточнику: <a href="http://www.autohotkey.com/forum/viewtopic.php?t=6772">Send mouse scrolls to window under mouse</a> - там много больше, чем тут.</p><p>Я взял оттуда код shimanov&#039;a, сократил его, немного модифицировал, добавил также идею Laszlo - ускорение прокрутки при быстром вращении колеса - и получилось довольно натурально, на мой взгляд.<br /></p><div class="codebox"><pre><code>WheelUp::
WheelDown::
  Critical
  If(A_ThisHotkey!=A_PriorHotkey || A_TimeSincePriorHotkey&gt;40) ; Определить скорость
    Scroll:= A_ThisHotkey=&quot;WheelUp&quot; ? 120&lt;&lt;16 : -120&lt;&lt;16       ; вращения колеса и
  Else                                                         ; задать скорость прокрутки.
    Scroll:= A_ThisHotkey=&quot;WheelUp&quot; ? 240&lt;&lt;16 : -240&lt;&lt;16

  CoordMode, Mouse, Screen
  MouseGetPos, mX, mY
  WinID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int&quot;, mX, &quot;int&quot;, mY)      ; ID (handle) окна под мышью.
  NextID:=DllCall(&quot;WindowFromPoint&quot;, &quot;int&quot;, mX, &quot;int&quot;, mY-20)

  SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %WinID%   ; 0x20A = WM_MOUSEWHEEL
  If (!ErrorLevel &amp;&amp; (WinID != NextID))
    SendMessage, 0x20A, %Scroll%, (mY&lt;&lt;16)|mX,, ahk_id %NextID%
Return</code></pre></div><p>Основная идея: определяется ID окна под курсором и вращение колеса посылается конкретно в это окно. &quot;Панель&quot; - это тоже окно (дочернее), но в AutoHotkey эти окошки принято называть контролами, а окнами называть только родительские окна. Это различие прослеживается и в соответствующих командах, что не всегда удобно. API-функция WindowFromPoint не делает таких различий.</p><p>&quot;Внимательный читатель&quot; может заметить, что зачем-то определяется ещё и ID в точке на 20 пикселов выше курсора (NextID). Это нужно, чтобы обойти один затык, который обнаружился, например, при прокрутке левой панели справки АНК: когда курсор попадает на название, не полностью умещающееся по ширине панели, это название выводится полностью в такой узенькой светлой рамочке. Эта &quot;рамочка&quot; оказалась тоже окном со своим ID. Так что вращение колеса начинает посылаться в неё, а прокрутка дерева останавливается. К счастью, это можно отследить - при этом SendMessage возвращает 0 вместо 1 - и отреагировать на это использованием NextID. Говорю &quot;к счастью&quot;, т.к. правая панель справки, например, всегда отвечает нулём. Из-за этого пришлось ввести ещё и проверку на совпадение WinID и NextID, чтобы не посылать в такие &quot;вечно нулевые&quot; окна 2 шага колеса вместо одного.</p><p>Использованное тут сообщение WM_MOUSEWHEEL имеет два параметра. Первый, wparam, - это &quot;количество вращения&quot;. Стандарт - 120, каких-то условных единиц. Если посылать меньше, то пока не накопится 120, никакой реакции окна не будет. Причём находиться это количество должно в старшем слове wparam, для этого и сдвиг на 16 бит влево. Если колесо вертеть быстро (время между шагами не больше 40 мс), скрипт будет посылать вдвое большее количество вращения. Знак определяет направление вращения: минус - колесо вниз.<br />Второй параметр, lparam, - координаты (экранные): в старшем слове Y, в младшем X.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Tue, 08 May 2007 13:54:16 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=2799#p2799</guid>
		</item>
	</channel>
</rss>
