<?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=11195</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=11195&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Об использовании произвольных клавиш в качестве модификаторов».]]></description>
		<lastBuildDate>Fri, 01 Jan 2016 14:54:00 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[AHK: Об использовании произвольных клавиш в качестве модификаторов]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=100078#p100078</link>
			<description><![CDATA[<p>Модификатор - клавиша, изменяющая действия других клавиш, нажатых вместе с собой. Это клавиши Ctrl, Alt, Fn, Win.<br />Как правило, действия других клавиш в сочетании с ними предопределены программами и ОС.<br />AutoHotkey позволяет сделать модификатор из любой клавиши, и определить действия других клавиш в слое вашего модификатора, разумеется.</p><p>Если вы хотитие сделать модификатор из некой клавиши, вам придется либо пожертвовать ее оригинальной функцией вовсе, либо перенести ее на момент отжатия этой клавиши.</p><p>Для примера возьмем клавишу AppsKey (контекстное меню):<br /></p><div class="codebox"><pre><code>
; * нужна, чтобы AppsKey вызывалась / не вызывалась в сочетаниях с модификаторами,
; например Shift+Apps (расширенное контекстное меню в проводнике).
*AppsKey::Return  ; Нажатие клавиши будет посылаться в момент ее отжатияия,
*AppsKey Up::
	If (A_PriorKey = &quot;AppsKey&quot;)  ; если в период м/у ее зажатием и отпусканием не были нажаты какие-либо еще клавиши.
		Send {Blind}{AppsKey}  ; Blind сохраняет зажатые клавиши зажатыми.
	; Например, без этой опции вместо при нажатии Shift+Apps будет послано просто Apps.
	Return

; Теперь можно создавать слой действий клавиш с нашим новым модификатором AppsKey:
#If GetKeyState(&quot;AppsKey&quot;, &quot;P&quot;)
	Left::WinMinimize A
	Up::WinMaximize A ; Развернуть окно
	Right::Send #{Right}
	vkBE::Send {Esc} ;.
	vkBF::Send ^{vk5a} ;/ - z
#If
$Esc::ExitApp</code></pre></div><p><span style="color: grey">*Примечание: в современных USB-клавах (сюда входят и встроенные в ноутбуки) у вас могут быть проблемы с одновременным нажатием некоторых клавиш, последняя клавиша не будет нажиматься. Особенно часто это бывает с рядом расположенными клавишами.<br />На PS/2 клавах можно зажать хоть все до одной клавиши, и ОС получит сигнал от каждой, но с большинсвом USB это не так.<br />В целях экономии производители помещают по нескольку клавиш на одну дорожку, что для офисных клавиатур вполне одправдано.<br />Разумееется к модификаторам Shift, Ctrl, Win проведена отдельная дорожка, чтобы их можно было нажимать в сочетании с любыми другими.<br />Разводка платы у всех производителей разная, некоторые не позволяют даже нажать одновременно стрелку вверх, вниз и пробел.<br />Перед покупкой проверить возможности клавы можно с помощью программки AquaKeyTest. Она отображает на экране все нажатые вами клавиши.</span></p><p>Так можно делать, пока вы не захотите создать горячие клавиши (далее - гк) типа (Alt/Shift/Ctrl)+Apps в противовес сочетаниям Apps+(Alt/Shift/Ctrl).<br />Допустим, вы сделали гк для сочетания Alt+AppsKey и повесили на нее действие.<br />Однако, в дополнение к вашему действию, при отпускании Apps сработает и гк *AppsKey Up:: (с последующим вызовом контексного меню).<br />Что же делать? Можно, конечно, убрать звездочку из гк *AppsKey Up::, а для Shift+AppsKey назначить новую гк.<br /><span style="color: grey">*Примечание: Поскольку уже есть запись *AppsKey::, запись !AppsKey:: скрипт просто проигнорирует. Потребуется запись вида Alt &amp; AppsKey::.</span></p><p>Но правильнее будет воспользоваться тем, что гк Alt &amp; AppsKey:: и *AppsKey:: являются конкурирующими.<br />Гк Alt &amp; AppsKey:: будет иметь преимущество над конкурирующей *AppsKey::, поэтому при нажатии Alt+AppsKey отработает только Alt &amp; AppsKey::, но не *AppsKey::.<br /><span style="color: grey">Отметим, что можно сделать и по-другому, использовав запись вида !AppsKey, но поместив *AppsKey:: и *AppsKey Up:: в условный блок [#If !GetKeyState(&quot;RAlt&quot;, &quot;P&quot;)].</span><br /></p><div class="codebox"><pre><code>Alt &amp; AppsKey::Send #{Right}

*AppsKey::
	AppsKeyHK:=true ; Введем переменную AppsKeyHK, чтобы узнать сработала ли гк *AppsKey::.
	Return
*AppsKey Up::
	if (AppsKeyHK &amp;&amp; (A_PriorKey = &quot;AppsKey&quot;)) ; Попробуйте заменить AppsKeyHK на 1 и нажать Alt+AppsKey
		Send {Blind}{AppsKey}
	AppsKeyHK:=false
	Return

#If GetKeyState(&quot;AppsKey&quot;, &quot;P&quot;)
	RAlt::MsgBox ; Заметьте, что Alt+AppsKey и AppsKey+Alt выполняют разные действия
	Left::WinMinimize A
	Up::WinMaximize A
	Right::Send #{Right}
	vkBE::Send {Esc} ;.
	*vkBF::Send {Blind}^{vk5a} ;/ - z   Зачем {Blind}? В моем редакторе Ctrl+Z - отмена, а Shift+Ctrl+Z - повтор. Таким образом я убиваю сразу 2 зайцев.
	*vkDC::Send {Blind}^{vk57} ;\ - w   Ctrl+W - закрытие вкладки. Догадайтесь сами, что произойдет по нажатию Apps+Shift+\
	*vkba::Send {Blind}^{vk53} ;; - s
#If
$Esc::ExitApp</code></pre></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;Тоже самое с использованием Input вместо служебной переменной A_PriorKey:</div><div class="fancy_spoiler"><div class="codebox"><pre><code>*AppsKey::
	; Input нужен чтобы узнать, были ли нажатия каких-либо клавиш в период между нажатием и отпусканием нашей клавиши.
	; Однако, Input не получает сведений о нажатии hotkeys, установленных из AutoHotkey.
	; Чтобы обойти эту проблему, hotkeys(включающие в себя нашу клавишу) должны при срабатывании устанавливают переменую KeyInterrupt в true.
	Input keys, L1V, {LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{Capslock}{Numlock}{PrintScreen}{Pause}
	If ((ErrorLevel = &quot;NewInput&quot;) &amp;&amp; !KeyInterrupt_AppsKey) ; Если Input прерван отпусканием AppsKey, и не было использовано горячих клавиш
		Send {Blind}{AppsKey} ; Blind сохраняет зажатые клавиши зажатыми. Например, без этой опции вместо Shift+Apps будет послано Apps.
	KeyInterrupt_AppsKey := false
	Return
*AppsKey Up::
	Input
	Return

#If GetKeyState(&quot;AppsKey&quot;, &quot;P&quot;)
	*vkdd:: ;]
		Send {Esc}
		KeyInterrupt_AppsKey:=true
		Return
	*Left::
		WinMinimize A
		KeyInterrupt_AppsKey:=true
		Return
	*Right::
		Send #{Right}
		KeyInterrupt_AppsKey:=true
		Return
	*vkdc:: ;\
		Send ^{vk57} ;w
		KeyInterrupt_AppsKey:=true
		Return
#If GetKeyState(&quot;AppsKey&quot;, &quot;P&quot;) &amp;&amp; !TurnOffAltTabSomeCuts
; С помощью TurnOffAltTabSomeCuts, shortcut-ы выключают сами себя до момента отпускания AppsKey
	*Down:: ; Эмуляция AltTab. Вызов - Apps+Down, навигация стрелками при зажатой клавише Apps
		TurnOffAltTabSomeCuts:=true
		Send {AltDown}{Tab}
		KeyWait, AppsKey
		TurnOffAltTabSomeCuts:=false
		Send {AltUp}
		KeyInterrupt_AppsKey:=true
		Return
	*Up:: ; Развернуть окно
		WinMaximize A
		KeyInterrupt_AppsKey:=true
		Return
#If
$Esc::ExitApp</code></pre></div></div></div><p>Еще один способ установить гк на Alt+AppsKey, в этот раз в условный блок попадает действие AppsKey при зажатом Alt:<br />В этом скрипте у нас сразу две эмуляции AltTab - на сочетании RAlt+Apps и на стрелках в слое модификатора AppsKey.<br /></p><div class="codebox"><pre><code>*AppsKey::
	AppsKeyHK:=true
	Return
*AppsKey Up::
	if (AppsKeyHK &amp;&amp; (A_PriorKey=&quot;AppsKey&quot;))
		Send {Blind}{AppsKey}
	AppsKeyHK:=false
	Return

; Эмуляция AltTab. Вызов - RAlt+Apps, Shift+RAlt+Apps. Навигация повторным нажатием Apps при зажатой клавише RAlt(+Shift)
; Эмуляция CtrlTab аналогично.
#If AppsComeTab:=(GetKeyState(&quot;RCtrl&quot;, &quot;P&quot;) || GetKeyState(&quot;RAlt&quot;, &quot;P&quot;))
	AppsKey::Tab ; конкурирующая с *AppsKey:: гк, будет иметь преимущество, т.к. устанавливается в #If.
	; Почему я не использовал * здесь? Запись вида клавиша::клавиша автоматически приводится к нужному виду,
	; подробнее об этом - https://autohotkey.com/docs/misc/Remap.htm

; Слой модификатора AppsKey
#If GetKeyState(&quot;AppsKey&quot;, &quot;P&quot;)
	Left::WinMinimize A
	Right::Send #{Right}
	vkBE::Send {Esc} ;.
	*vkBF::Send {Blind}^{vk5a} ;/ - z
	*vkDC::Send {Blind}^{vk57} ;\ - w
	*vkba::Send {Blind}^{vk53} ;; - s
#If (!TurnOffSelfHK &amp;&amp; GetKeyState(&quot;AppsKey&quot;, &quot;P&quot;)) ; С помощью TurnOffSelfHK, гк выключают сами себя до момента отпускания AppsKey
	Down:: ; Эмуляция AltTab. Вызов - Apps+Down, навигация стрелками при зажатой клавише Apps
		TurnOffSelfHK:=true
		Send {AltDown}{Tab}
		KeyWait, AppsKey
		TurnOffSelfHK:=false
		Send {AltUp}
		Return
	Up::WinMaximize A ; Развернуть окно
#If
$Esc::ExitApp</code></pre></div><p>В Windows &gt; 7 c эмуляцией AltTab <a href="https://autohotkey.com/board/topic/99538-alt-tab-menu-doesnt-work/#entry629517">не все так просто</a>.</p>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Fri, 01 Jan 2016 14:54:00 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=100078#p100078</guid>
		</item>
	</channel>
</rss>
