<?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=12908</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=12908&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Замедление мыши».]]></description>
		<lastBuildDate>Sat, 02 Sep 2017 16:33:27 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=119108#p119108</link>
			<description><![CDATA[<p>Можно использовать хук для той же цели:<br /></p><div class="codebox"><pre><code>SetBatchLines, -1
SetMouseDelay, -1
OnExit, Exit

hHookMouse := DllCall(&quot;SetWindowsHookEx&quot; . (A_IsUnicode ? &quot;W&quot; : &quot;A&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

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

; F12::MouseMove(20, 10)

LowLevelMouseProc(nCode, wParam, lParam)
{
	static x_prev, y_prev, stop
	Critical
	CoordMode Mouse, Screen

	if (nCode &lt; 0 || wParam != 0x200 || stop)   ; WM_MOUSEMOVE = 0x200
		Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)

	x := NumGet(lParam+0, 0), y := NumGet(lParam+0, 4)

	y_prev := (y_prev = &quot;&quot;) ? y : y_prev
	x_prev := (x_prev = &quot;&quot;) ? x : x_prev

	MouseMove, Round((-x+x_prev)/2), Round((-y+y_prev)/2), 0, R

	; If (abs(x-x_prev)&gt;140 || abs(y-y_prev)&gt;140) { ; ненормальные смещения
	; 	stop := true
	; 	MouseGetPos _x, _y
	; 	OutputDebug % x-x_prev &quot; x=&quot; x &quot;, &quot; y-y_prev &quot; y=&quot; y &quot;. &quot;  x &quot; &quot; y &quot; - &quot; _x &quot; &quot; _y
	; 	ExitApp
	; }
	; Else
		; MouseMove(Round((-x+x_prev)/2), Round((-y+y_prev)/2))

	x_prev := x, y_prev := y
	Return 1
}

MouseMove(x, y) {
	DllCall(&quot;mouse_event&quot;, UInt, MOUSEEVENTF_MOVE:=0x1, Int, x, Int, y, UInt, 0, Int, 0)
}</code></pre></div><p>Но с перемещением мыши посредством DllCall mouse_event проблема — при резком движении хук выдает неверные координаты и перемещение идет вразнос.<br />Кто понимает в чем причина?</p>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Sat, 02 Sep 2017 16:33:27 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=119108#p119108</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118832#p118832</link>
			<description><![CDATA[<p>По основной теме (замедление мыши) значительно продвинулся. За счет использования <a href="http://forum.script-coding.com/viewtopic.php?id=12951">нового подхода</a> добился улучшения общего качества работы скрипта (снизилась нагрузка на процессор, увеличилась плавность движения мыши -таймер 500 мкс). Играл по сети в DOOM, никаких проблем не возникало. Приятно теперь играть - в режиме прицеливания мышь двигается мягко, без скачков.<br /></p><div class="codebox"><pre><code>
#SingleInstance force
#Persistent
#include CLR.ahk
asm := CLR_LoadLibrary(&quot;WaitableTimer\WaitableTimer.dll&quot;)

wt1 := asm.CreateInstance(&quot;WaitableTimer&quot;)
MyTimer1 := wt1.Create(Func(&quot;Test&quot;), 1)
MyTimer1.Start() ;создаем первый таймер -1мс

loop 
{
++ZX
	if (ZX=1200) ;выдержка 500 мкс (кол-во циклов находим опытным путем)
	{
	ZX:=0
	Break   
	}
}	
wt2 := asm.CreateInstance(&quot;WaitableTimer&quot;)
MyTimer2 := wt2.Create(Func(&quot;Test&quot;), 1)
MyTimer2.Start() ;через 500 микросекунд создаем второй таймер на 1 мс
return

Test(){ ;на выходе получаем частоту обращения в два раза выше(период 500 микросекунд вместо 1мс)
Gosub, s1
}
 
s1:
MouseGetPos, X, Y
if Joy7
{
   if (ABS(OldX-X)&gt;=2)
   dx:=2*(OldX-X)//3
   else
   dx:=0
   
   if (ABS(OldY-Y)&gt;=2)
   dy:=2*(OldY-Y)//3
   else
   dy:=0
   
   if (dx or dy)
   DllCall(&quot;mouse_event&quot;, uint, 1, int, dx, int, dy, uint, 0, int, 0)
} 
MouseGetPos, OldX, OldY
Return
</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (sabir.yanin2014)]]></author>
			<pubDate>Sun, 27 Aug 2017 23:09:03 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118832#p118832</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118232#p118232</link>
			<description><![CDATA[<p>Вот <a href="http://forum.script-coding.com/viewtopic.php?id=12452">класс выкладывал</a> тут тоже.</p>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Sun, 13 Aug 2017 20:27:33 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118232#p118232</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118231#p118231</link>
			<description><![CDATA[<p>На офф. форуме есть темы про объяснение классов для чайников.<br />В оригинальной справке (которая в меню пуск) написано тоже, поиском найдете.</p>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Sun, 13 Aug 2017 20:24:45 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118231#p118231</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118230#p118230</link>
			<description><![CDATA[<p><strong>stealzy</strong>, спасибо. Может подскажите где можно почитать, чтобы более-менее доступным языком было написано про классы?</p>]]></description>
			<author><![CDATA[null@example.com (sabir.yanin2014)]]></author>
			<pubDate>Sun, 13 Aug 2017 20:18:57 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118230#p118230</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118224#p118224</link>
			<description><![CDATA[<p><strong>sabir.yanin2014</strong><br />Класс не мой, и в нем фишки класса практически и не используются, единственное — при инициализации класса вычисляются статические переменные, с ф-ией они вычисляются лишь при первом вызове, что займет время, что в данном случае неприемлемо.</p><p>Если спрашиваете вообще за классы, то к ним приходят, когда становится тесно в функциях.<br />Пример: пул ф-ий, которые делят м/у собой общие данные. Делать эти данные глобальными - неудобно, передавать из ф-ии в ф-ию в параметрах - тоже неудобно, не всегда возможно. И вообще, когда ф-ий становится несколько десятков, их приходится организовывать.<br />Функции при этом никуда не деваются, потому что классы состоят из ф-ий и данных.</p>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Sun, 13 Aug 2017 19:54:46 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118224#p118224</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118219#p118219</link>
			<description><![CDATA[<p><strong>stealzy</strong><br />Настолько сложно, что напоминает алжирский. Зачем вообще были придуманы классы? Чем они лучше простых функций?<br />Как вы к ним пришли? И что меня, простого смертного отделяет от этого понимания?</p>]]></description>
			<author><![CDATA[null@example.com (sabir.yanin2014)]]></author>
			<pubDate>Sun, 13 Aug 2017 19:02:41 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118219#p118219</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118217#p118217</link>
			<description><![CDATA[<p>Это явно сложнее.</p><div class="quotebox"><cite>stealzy пишет:</cite><blockquote><p>Э, видимо из контекста неясно, что я говорю про встроенные команды языка.</p></blockquote></div><p>А, я просто не понял, к чему, в том примере встроенный Sleep и не используется.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Sun, 13 Aug 2017 18:24:34 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118217#p118217</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118209#p118209</link>
			<description><![CDATA[<p><strong>stealzy</strong>, <a href="https://autohotkey.com/docs/commands/Sleep.htm#ShorterSleep">ShorterSleep</a></p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Sun, 13 Aug 2017 17:22:52 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118209#p118209</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118203#p118203</link>
			<description><![CDATA[<div class="quotebox"><blockquote><p>Проще всего было бы использовать таймер, но оказалось что таймер не дает требуемую частоту опроса, так при заявленном 5 мс -<br />SetTimer, s1, 5 на деле таймер дает 15,6 мс.</p></blockquote></div><p>Встроенные команды языка Sleep и таймеры всегда кратны 10-15 мс промежутку и не могут быть меньше.<br />Вот <a href="https://autohotkey.com/boards/viewtopic.php?t=29957&amp;start=20">так придумали</a> с таймерами, и еще одна альтернатива Sleep:<br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;Sub 10ms Sleep</div><div class="fancy_spoiler"><div class="codebox"><pre><code>SetBatchLines -1
sle := new pSleep
st := A_TickCount
Loop 100
	sle.do(5)
MsgBox % A_TickCount - st

class pSleep
{
	static F:=pSleep.getQPF(), res:=pSleep.getTimerResolution()
	do(t) {
		crit:=A_IsCritical
		Critical On
		DllCall(&quot;QueryPerformanceCounter&quot;, &quot;Int64P&quot;, sT1)
		res:=this.res, dt:=0
		; Do regular sleep before qpc loop, if t is long enough.
		if (t&gt;res)
			(DllCall(&quot;Sleep&quot;, &quot;Int&quot;, t-res), DllCall(&quot;QueryPerformanceCounter&quot;, &quot;Int64P&quot;, sT2), dt:=(sT2-sT1)*1000/this.F)
		t-=dt, DllCall(&quot;QueryPerformanceCounter&quot;, &quot;Int64P&quot;, loopStart), loopTic:=loopStart
		while (loopTic-loopStart&lt;t*this.F/1000)
			DllCall(&quot;QueryPerformanceCounter&quot;, &quot;Int64P&quot;, loopTic)
		Critical % crit
	}
	getTimerResolution() {
		DllCall(&quot;ntdll.dll\NtQueryTimerResolution&quot;, &quot;UPtr*&quot;, MinimumResolution, &quot;UPtr*&quot;, MaximumResolution, &quot;UPtr*&quot;, CurrentResolution)
		return Ceil(CurrentResolution/10000) ; Resolutions are reported as 100-nanoseconds
	}
	getQPF() {
		DllCall(&quot;QueryPerformanceFrequency&quot;, &quot;Int64P&quot;, F)
		return F
	}
}</code></pre></div></div></div>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Sun, 13 Aug 2017 16:45:52 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118203#p118203</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118201#p118201</link>
			<description><![CDATA[<p>Если я правильно понял, то при нажатии определенной клавиши, включается специальный режим, который после того, как вы сместите мышку например на 10 прикселей вправо, сместит после этого её на половину (5 пикселей) влево? С таким скриптом легко бан получить в играх.</p>]]></description>
			<author><![CDATA[null@example.com (belyankin12)]]></author>
			<pubDate>Sun, 13 Aug 2017 16:31:07 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118201#p118201</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Замедление мыши]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=118199#p118199</link>
			<description><![CDATA[<p>Мне было интересно найти код который помог бы мне в процессе игры облегчить прицеливание- а именно во время прицеливания снижать чувствительность мыши. Кто-то возразит мне что зачем изобретать велосипед, если на игровых девайсах уже предусмотрена возможность изменять DPI? Кому как удобно.<br />	Для себя я придумал &quot;внешний&quot; способ переключения DPI, а именно-удерживая какую-то конкретную клавишу клавиатуры я уменьшаю чувствительность мыши, при отпускании клавиши чувствительность восстанавливается. Искал решения по этому вопросу на форуме, что-то похожее было:<br /></p><div class="codebox"><pre><code>
F1::
SPI_GETMOUSESPEED = 0x70
SPI_SETMOUSESPEED = 0x71
; Retrieve the current speed so that it can be restored later:
DllCall(&quot;SystemParametersInfo&quot;, UInt, SPI_GETMOUSESPEED, UInt, 0, UIntP, OrigMouseSpeed, UInt, 0)
; Now set the mouse to the slower speed specified in the next-to-last parameter (the range is 1-20, 10 is default):
DllCall(&quot;SystemParametersInfo&quot;, UInt, SPI_SETMOUSESPEED, UInt, 0, UInt, 3, UInt, 0)
KeyWait F1 ; This prevents keyboard auto-repeat from doing the DllCall repeatedly.
return

F1 up::DllCall(&quot;SystemParametersInfo&quot;, UInt, 0x71, UInt, 0, UInt, OrigMouseSpeed, UInt, 0) ; Restore the original speed.
return
</code></pre></div><p>Но проблема в том что данный код не работает в играх!<br />	Мое решение состояло в том чтобы по таймеру через период времени компенсировать 50% движения мыши (если мышь сдвинулась за период на 10 пикселей, то скрипт пусть вернет половину-5 пикселей назад. Таким способом я снижаю чувствительность вдвое).<br />Проще всего было бы использовать таймер, но оказалось что таймер не дает требуемую частоту опроса, так при заявленном 5 мс -<br />SetTimer, s1, 5 на деле таймер дает 15,6 мс. Это легко увидеть:<br /></p><div class="codebox"><pre><code>
SetBatchLines -1
#Persistent
SetTimer, s1, 5 

s1:
++DR
if (DR=100)
{
stop:=A_TickCount,DR:=0
dT:=(stop-start)/100
start:=A_TickCount
ToolTip, продолжительность периода=%dT%  
}
Return 
</code></pre></div><p> <br />С такой низкой частотой мой код работал плохо, мышь перемещалась скачкообразно. Чтобы сделать эти скачки невидимыми глазу нужно увеличить частоту опроса. Оказывается есть способ снизить время периода но при этом нужно прибегнуть к DLL и отказаться от таймера.<br /></p><div class="codebox"><pre><code>
SetBatchLines -1  ; Ensures maximum effectiveness of this method.

SleepDuration = 1  ; This can sometimes be finely adjusted (e.g. 2 is different than 3) depending on the value below.
TimePeriod = 3 ; Try 7 or 3.  See comment below.
; On a PC whose sleep duration normally rounds up to 15.6 ms, try TimePeriod=7 to allow
; somewhat shorter sleeps, and try TimePeriod=3 or less to allow the shortest possible sleeps.

DllCall(&quot;Winmm\timeBeginPeriod&quot;, uint, TimePeriod)  ; Affects all applications, not just this script&#039;s DllCall(&quot;Sleep&quot;...), but does not affect SetTimer.
Iterations = 50
StartTime := A_TickCount

Loop %Iterations%
    DllCall(&quot;Sleep&quot;, UInt, SleepDuration)  ; Must use DllCall instead of the Sleep command.

DllCall(&quot;Winmm\timeEndPeriod&quot;, UInt, TimePeriod)  ; Should be called to restore system to normal.
MsgBox % &quot;Sleep duration = &quot; . (A_TickCount - StartTime) / Iterations
</code></pre></div><p>	Вот что у меня получилось:<br /></p><div class="codebox"><pre><code>
SetBatchLines -1
SleepDuration:=1,TimePeriod:=3 
DllCall(&quot;Winmm\timeBeginPeriod&quot;, uint, TimePeriod)
Loop
{ 
DllCall(&quot;Sleep&quot;, UInt, SleepDuration)  
Gosub, s1
}

s1:
MouseGetPos, X, Y
if GetKeyState(&quot;n&quot;,&quot;P&quot;)
{
   If (ABS(OldX-X)&gt;=2)
   dx:=Floor((OldX-X)/2)
   else
   dx:=0
   
   If (ABS(OldY-Y)&gt;=2)
   dy:=Floor((OldY-Y)/2)
   else
   dy:=0
   
   if (dx or dy)
   DllCall(&quot;mouse_event&quot;, uint, 1, int, dx, int, dy, uint, 0, int, 0)
} 
MouseGetPos, OldX, OldY
return

*n::Return 

#Esc::
DllCall(&quot;Winmm\timeEndPeriod&quot;, UInt, TimePeriod)
ExitApp  
</code></pre></div><p>	При таком способе мне удалось снизить длительность периода до 0,9-1 мс. При нажатии клавиши N курсор замедляется и это справедливо не только в Windows но и в играх. Скачки практически незаметны. Я доволен, может кому-то тоже пригодится:).</p>]]></description>
			<author><![CDATA[null@example.com (sabir.yanin2014)]]></author>
			<pubDate>Sun, 13 Aug 2017 15:29:01 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=118199#p118199</guid>
		</item>
	</channel>
</rss>
