<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=10871&amp;type=atom" />
	<updated>2015-08-18T08:29:40Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=10871</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96566#p96566" />
			<content type="html"><![CDATA[<p><strong>yalanne</strong> Спасибо, правда открыв пост и почитал бегло не очень понял. </p><p>Перечитал - понял, но у меня лично, она не будет работать - надо её переписывать, но у меня.<br />1. Чтение и запись INI-файлов это функция.<br />2.&nbsp; Hotkey у меня функция и делает больше чем просто назначение - генерация справки в GUI и т.д.</p><p>P.S. Спасибо ещё раз и как пример.&nbsp; </p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;Чтение INI в виде функции (моя реализация)</div><div class="fancy_spoiler"><div class="codebox"><pre><code>;---------------------------Чтение и проверка INI-файла--------------------------------------------

fnIniReadAndСheck(ByRef OutputINI, FilenameINI, SectionINI := &quot;&quot;, KeyINI := &quot;&quot;
                  , KeyTrFl := True, ByRef varLen := 0
                  , ByRef SkipSec := False,  ByRef SkipVar := False, vWait :=  35)
{
  if FileExist(FilenameINI)
        {
          IniRead, OutputINI, %FilenameINI%, % SectionINI, % KeyINI
          varLen  :=  StrLen(OutputINI)
        }  
       Else
        {
          NumError := 1
          fnIniErrorOut(NumError, FilenameINI, SectionINI,  KeyINI, vWait) ; нет файла
          Return
        }
  
  ; Просто пропуск Секции/Переменной - ошибка игнорируется
  If (SkipSec || SkipVar)
        {
          If (SkipSec) ; У секции более высокий приоритет, если SkipSec = SkipVar = True
                OutputINI := SectionINI
            Else If (SkipSec)
                OutputINI := SectionINI                
          Return True
         }
  
  if ((OutputINI) &amp;&amp; (OutputINI != &quot;ERROR&quot;))
            Return True ; переменная есть
         
  If (!OutputINI)
        {
          If (varLen = 0)
              {
                If (KeyTrFl)
                    {
                      NumError := 3
                      fnIniErrorOut(NumError, FilenameINI, SectionINI,  KeyINI, vWait) ; Пустые переменные не допустимы
                      Return                                              
                    }
                  Else
                    Return False ; Пустая переменная, не может быть это 0(varLen = 0)
              }
            Else
              Return False  ; Не пустая переменная(varLen != 0) может быть равна 0
        }
  
  ; Пропуск Секции/Переменной при ошибке
  If ((OutputINI = &quot;ERROR&quot;) &amp;&amp; (SkipSec || SkipVar)) ; У секции более высокий приоритет, если SkipSec = SkipVar = True
        {
          If (SkipSec)
                OutputINI := SectionINI
            Else If (SkipSec) (SkipSec)
                OutputINI := SectionINI                
          Return False
         }
         
  ; Пропуск Переменной в Секции при ошибке
  If ((OutputINI = &quot;ERROR&quot;) &amp;&amp; SkipVar)
        {
          OutputINI := SectionINI
          Return False
         }
         
  If (OutputINI = &quot;ERROR&quot;) ; Ошибка отсутствует Секция и/или Переменная
        {
          
          NumError := 2
          fnIniErrorOut(NumError := 2, FilenameINI, SectionINI,  KeyINI, vWait) ; не верная переменная или секция
          Return
        }
}
;--------------------------------------------------------------------------------------------

;--------------------Диагностика об ошибках в INI (fnIniReadAndСheck)------------------------
fnIniErrorOut(NumError, ByRef FilenameINI := &quot;&quot;, ByRef SectionINI := &quot;&quot;,  ByRef KeyINI := &quot;&quot;, SecWait :=  35, ByRef cMsgBoxType := 8208)
{
Global fnIniErrorOut_LabelMin, fnIniErrorOut_LabelExit


  If (NumError = 0)
        {
          fnIniErrorOut_LabelMin  := &quot;ErrorOutMin&quot;
          fnIniErrorOut_LabelExit := &quot;ErrorOutExit&quot;
          ;MsgBox На внутренние обработчики т.к. NumError = 0
          Return
        }
  Else If (NumError = 1000)
            {
              ;MsgBox На внешние обработчики т.к. NumError = 1000
              Return
            }

; cMsgBoxType по умолчанию равна AllMainConst.ahk
; сMsgBoxError_Ok         :=0+8192+16 ;only an OK button + Task Modal + Icon Hand (stop/error)


  arIniErrorTXT :=  [&quot; Отсутствует INI-файл&quot;                                        ; = 1
                    ,&quot; В имени переменной/её нет/ошибка в имени секции.&quot;            ; = 2
                    ,&quot; Переменная не может быть пустой.&quot;                            ; = 3
                    ,&quot; Переменная содержит недопустимое значение.&quot;                  ; = 4
                    ,&quot; Переменная должна быть числом.&quot;                              ; = 5
                    ,&quot; Переменная должна быть целым числом.&quot;                        ; = 6
                    ,&quot; Переменная должна быть числом с плавающей точкой.&quot;           ; = 7
                    ,&quot; Переменная меньше допустимого значения и не число.&quot;          ; = 8
                    ,&quot; Переменная больше допустимого значения и не число.&quot;          ; = 9
                    ,&quot; Переменная  вне допустимого диапазона или не число.&quot;         ; = 10
                    ,&quot; Переменная содержит не верный путь и/или программу.&quot;         ; = 11
                    ,&quot; Переменная содержит не верный путь.&quot;                         ; = 12
                    ,&quot; Переменная не число, ни целое/ни с плавающей точкой.&quot;        ; = 13
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 14
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 15
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 16
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 17
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 18
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 19
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 20
                    ,&quot; Резерв или ошибка в программе.&quot;                              ; = 21
                    ,&quot; Резерв или ошибка в программе.&quot;]                             ; = 22

  Error_TXT :=  arIniErrorTXT[NumError]
  cWait :=  SecWait
  Gosub %fnIniErrorOut_LabelMin%
    cTitle      :=  &quot;`n`n Ошибка в INI-файле&quot; ;Титул MsgBox
    cMsgErr     :=  &quot;                                 ОШИБКА В INI-ФАЙЛЕ`n`n  -&gt;&gt;&quot; Error_TXT
    cTxtErrAd1  :=  &quot;`n`n Файл : &quot; FilenameINI
    cTxtErrAd2  :=  &quot;`n Секция = [&quot; SectionINI &quot;] `n Ключ = &quot; KeyINI
    ;cWait       :=  35
    cTxtErrAd3  :=  &quot;`n`n Выход из программы(Тайм-аут = &quot; cWait &quot; сек).&quot;
      MsgBox % cMsgBoxType, %cTitle%, %cMsgErr% %cTxtErrAd1% %cTxtErrAd2% %cTxtErrAd3%, %cWait%      
    Gosub %fnIniErrorOut_LabelExit%
Return

ErrorOutMin:
Thread, NoTimers
Critical 
    ;Send, {Escape}
    Sleep, 600
    WinMinimize, A
Critical , Off
Thread, NoTimers, false 
Return

ErrorOutExit:
  ExitApp
Return
}
;--------------------------------------------------------------------------------------------</code></pre></div></div></div>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-18T08:29:40Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96566#p96566</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96559#p96559" />
			<content type="html"><![CDATA[<p>Написал функцию для более удобной работы:<br /></p><div class="codebox"><pre><code>Class remapping
{
Static ListLoad_ini := [],    LoadList := [],File_ini
    __New(apply=0,file=&quot;HK&quot;,Section=&quot;keys&quot;)
    {    
        ListLoad_ini := [], this.File_ini := A_ScriptDir &quot;\&quot; file &quot;.ini&quot;
        If !FileExist(this.File_ini) 
            FileAppend, % &quot;[&quot; Section &quot;]&quot;, % this.File_ini
        IniRead, Data,% this.File_ini, %Section%
        Loop, parse, Data, `n   
            RegExMatch(A_LoopField, &quot;O)(.*?)::(.*)&quot;, m),    this.ListLoad_ini.Insert(m)
        if apply
            this.Load()
        return this
    }
    Load(key=&quot;all&quot;)
    {
        for i,k in this.ListLoad_ini
        if (key=&quot;all&quot;) or (key=k[1])
        {
            this.LoadList.Insert(k)
            Hotkey, % k[1], pressed, On
        }
        return this    
    }
    Save(Section=&quot;keys&quot;)
    {
        FileDelete % this.File_ini
        for i,k in this.LoadList
            IniWrite,% k[1] &quot;::&quot; k[2],% this.File_ini, %Section%
        return this
    }
    Add(key1,key2)
    {
        for i,k in this.LoadList
            if (k[1] = key1) and (k[2] = key2)
            return this
        this.LoadList.Insert([key1,key2])
        Hotkey, % key1, pressed, On
        return this
    }
    Remove(key1=&quot;all&quot;)
    {
        loop % this.LoadList.MaxIndex()
        {
            if (key1=&quot;all&quot;) or (this.LoadList[A_Index][1] = key1)
            {
                Hotkey, % this.LoadList[A_Index][1],Off
                this.LoadList.Remove([A_Index])
            }
        }
    }
    Edit(key1,key2)
    {
        this.remove(key1)
        this.add(key1,key2)
    }
    _()
    {
        pressed:
        for i,k in remapping.LoadList
        if (k[1] = A_ThisHotkey)
            Send % k[2]
        return this
    }
}</code></pre></div><p>Отступив пару строчек вниз пишем <strong>RG := new remapping(<em>Options</em>)</strong><br />В этой функции есть 3 параметра:<br /></p><ul><li><p>0 - Загружает в память настройки из ini файла\1 - загружает и применяет. По Умолчанию 0</p></li><li><p>Имя файла настроек(без расширения .ini) По умолчанию <em>H</em>K </p></li><li><p>Имя секции в файле настроек. По умолчанию <em>Keys</em></p></li></ul><p>Если просто написать RG := new remapping(1), то скрипт просто загрузит и применит клавиши, оставив настройки загрузки по стандарту.</p><p>Функция&nbsp; <strong>RG.Load()</strong> аналог первого параметра из первой функции. Применяет клавиши. Отличие от первого варианта то, что можно указать конкретную клавишу вместо всего что есть в списке.(если функция пуста загружает все)<br />Пример для загрузки кнопки A из ini RG.Load(&quot;A&quot;)</p><p>Дальше идет функция <strong>RG.Add(key1,key2)</strong> она служит для добавления клавиш( не сохраняет в ini. для сохранения есть отдельная функция)</p><p>Функция <strong>RG.Remove(key1)</strong> удаляет из списка клавишу, если не указанна клавиша стирает все.</p><p>Для редактирования есть функция <strong>RG.Edit(key1,key2)</strong>.</p><p>Ну и пока что последняя функция это сохранения<strong> RG.Save()</strong></p><p>p.s все key указываются в кавычках &quot;&quot;</p>]]></content>
			<author>
				<name><![CDATA[yalanne]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32850</uri>
			</author>
			<updated>2015-08-17T20:13:21Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96559#p96559</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96510#p96510" />
			<content type="html"><![CDATA[<p><strong>yalanne</strong> Ещё раз спасибо.<br /><strong>serzh82saratov</strong> Спасибо за общее направление.</p><p>Думаю, что вопрос закрыт, пошёл переписывать код.</p>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-17T10:47:06Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96510#p96510</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96509#p96509" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Indomito пишет:</cite><blockquote><p>Этот вариант рабочий или нет, т.е. с оговорками?</p></blockquote></div><p>Ну да рабочий.</p>]]></content>
			<author>
				<name><![CDATA[yalanne]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32850</uri>
			</author>
			<updated>2015-08-17T10:41:59Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96509#p96509</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96506#p96506" />
			<content type="html"><![CDATA[<p><strong>yalanne</strong> Вроде понял и тут же запутался <strong>;если клавиша-цифра то возможно собьет индекс.</strong> Так как надо писать с точки зрения надёжности?<br />Просто у меня может встретится что угодно, проверить клавишу я могу, но конфликт <strong>цифры-клавиши и индекса</strong> точно нет.</p><p>Этот вариант рабочий или нет, т.е. с оговорками? </p><div class="codebox"><pre><code>ar := [ [&quot;q&quot;,&quot;+a&quot;, &quot;remap&quot;] , [&quot;w&quot;,&quot;s&quot;, &quot;remap1&quot;] ]
for i,sasa in ar
    Hotkey, % sasa[1], % sasa[3], useerrorlevel
return

remap:
for i,k in ar
    if (k[1] = A_ThisHotkey)
        Send % k[2]
Return

remap1:
for i,k in ar
    if (k[1] = A_ThisHotkey)
        Send % k[2]
Return</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-17T10:15:08Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96506#p96506</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96505#p96505" />
			<content type="html"><![CDATA[<div class="codebox"><pre><code>; Если вот так добавлять то это индекс. тут просто добаляется цифра в порядке возростания.
test1 := [&quot;A&quot;,&quot;B&quot;,&quot;C&quot;]
test1.Insert(&quot;D&quot;)

; А если так то ключ. 
test2 := []
test2[текст_ключ] := &quot;текст&quot;

msgbox % test1[1]
    . &quot;`n&quot; test2[текст_ключ]
    

; И можно комбинировать
test3 := []
test3.Insert(&quot;по индексу&quot;)
test3[text] := &quot;По тексту&quot;

msgbox % test3[1]
    . &quot;`n&quot; test3[text]
    
;если клавиша-цифра то возможно собьет индекс.</code></pre></div>]]></content>
			<author>
				<name><![CDATA[yalanne]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32850</uri>
			</author>
			<updated>2015-08-17T09:53:58Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96505#p96505</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96504#p96504" />
			<content type="html"><![CDATA[<p><strong>yalanne</strong> Да, я понял. А по циклу я то сделал, ещё вчера, я про это. </p><div class="codebox"><pre><code>remap:
for i,k in ar
    if (k[1] = A_ThisHotkey)
        Send % k[2]</code></pre></div><p> А вот как без цикла? Активировать HotKey с <strong>::</strong> Что бы убрать проверку - адресация по ключу?</p><p>И вот это. </p><div class="codebox"><pre><code>m1 это не индекс а та клавиша которая нажата физически, m2 собственно та клавиша,
 которая будет нажиматься в системе.
А в таком массиве [] работа может быть не только по индексу но и по ключу.</code></pre></div><p> Это не вызовет ошибок или повторов? <br />Мне не понятно когда индекс, а когда ключ, т.е. нет прямых указаний.</p><p>P.S. Знаю что глупый вопрос, просто я так ранее не делал.</p><p><strong>UPD</strong></p><p>Блин, я же забыл о символических ключах и перепутал их с индексом, правда всё равно путаюсь... надо перечитать справку по массивам.</p><p><strong>Позже...</strong><br />Всё, разобрался, а то в голове путаница была. </p><div class="codebox"><pre><code>ar := [ [&quot;q&quot;,&quot;+a&quot;, &quot;remap&quot;] , [&quot;w&quot;,&quot;s&quot; &quot;remap&quot;] ]
for i,sasa in ar
    ;Добавить проверку и инициализацию.
    Hotkey, % sasa[1], % sasa[3], useerrorlevel
return

remap:
for i,k in ar
    if (k[1] = A_ThisHotkey)
        Send % k[2]
Return</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-17T09:32:28Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96504#p96504</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96503#p96503" />
			<content type="html"><![CDATA[<p>m1 это не индекс а та клавиша которая нажата физически, m2 собственно та клавиша которая будет нажиматься в системе.<br />А в таком массиве [] работа может быть не только по индексу но и по ключу.<br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;пример</div><div class="fancy_spoiler"><div class="codebox"><pre><code>A := []
A[b] := &quot;C&quot;
msgbox % A[b]</code></pre></div></div></div><div class="quotebox"><cite>Indomito пишет:</cite><blockquote><p>Уберём чтение и за основу возьмем, скажем, двухмерный массив:</p></blockquote></div><div class="codebox"><pre><code>ar := [ [&quot;q&quot;,&quot;a&quot;] , [&quot;w&quot;,&quot;s&quot;] ]
for i,k in ar
    Hotkey, % k[1], remap, useerrorlevel
return

remap:
for i,k in ar
    if (k[1] = A_ThisHotkey)
        Send % k[2]
</code></pre></div><p>for разделяет массив на маленькие массивы. <br />В этом примере уже идет работа с индексами, а не с ключами.</p>]]></content>
			<author>
				<name><![CDATA[yalanne]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32850</uri>
			</author>
			<updated>2015-08-17T09:18:22Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96503#p96503</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96500#p96500" />
			<content type="html"><![CDATA[<p>-del</p>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-17T07:18:48Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96500#p96500</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96498#p96498" />
			<content type="html"><![CDATA[<p><strong>Alectric</strong> Спасибо - гляну.</p><p><strong>Drugoy</strong> Да, я читал это, но подумал... мало ли есть метод.</p><p><strong>serzh82saratov</strong> Я сначала и не понял что ты сделал/написал, но когда начал разбираться то понял.<br /> </p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;Написал такой INI, думал не сработает, глупо конечно.</div><div class="fancy_spoiler"><div class="codebox"><pre><code>[keys]
+a::E
^s::e
!d::Q</code></pre></div></div></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;А вот код, поставил меня в тупик, то что я не понял - поставил комментарии.</div><div class="fancy_spoiler"><div class="codebox"><pre><code>;IniWrite, *1::2`n*3::`n*2::1, %A_ScriptDir%\HK.ini, keys

ar := []
IniRead, Data, %A_ScriptDir%\HK.ini, keys
Loop, parse, Data, `n   
{ 
    RegExMatch(A_LoopField, &quot;(.*?)::(.*)&quot;, m) ; Тут всё почти понятно, но две строки ниже...
    ar[m1] := m2 ; m1 - индекс, но ниже это Hotkey-клавиша.
    Hotkey, %m1%, remap, useerrorlevel ; Я вот про это, хотя клавиша и есть код, но... т.е. непонятно.
}
Return

remap: 
    Send % ar[A_ThisHotkey] ; А это точно не понятно, адресация по нажатой, это как.
    Return</code></pre></div></div></div><p> Мне нужно понимать, что я пишу, иначе я точно запутаюсь - код у меня и так весьма большой за 3к строк перевалил - просто я потом ошибки не найду.</p><p>Можешь упростить свой пример или же дашь пояснения?</p><p>Уберём чтение и за основу возьмем, скажем, двухмерный массив: <strong>ar := [[&quot;q&quot;,&quot;a&quot;],[&quot;w&quot;,&quot;s&quot;]]</strong> т.е. пары нажимаемая и посылаемая клавиши.&nbsp; Повтори, но попроще, для особенно не одарённых, а?</p><p>Я сам сделал на основе IF методом перебора в массиве, но твой пример меня на 99% просто убил.</p><p>Почему прошу? <br />У меня до активации каждой клавиши, проверка её на метку заглушку, а потом ещё 3-5 проверок, после чего конвертация управляющих клавиш в акронимы, а уж потом активация на реальную функцию и ещё строится справка в виде GUI-Help, если ошибка, то генерация в чём допущена ошибка и в каком месте INI.</p><p>Фрагмент одного из INI-файлов.<br /><strong>Было (исходный текст в INI):</strong> </p><div class="codebox"><pre><code>;Безусловный выход
NameExitTotalKeys=Безусловный выход
ExitTotalKeys=~ Ctrl Shift  Esc
LabelExitTotalKeys=lExitTotalKeys</code></pre></div><p><strong>Стало (для работы HotKey):</strong> ExitTotalKeys=~^+ESC</p><p>P.S. Для справки —&nbsp; поверка, разборка, активация и деактивация HotKey. Тут почти всё, что относится к HotKey, да, это к моей просьбе не имеет отношения, но активатор у меня один, и если их станет несколько то будет сложно <em>&quot;найти концы&quot;</em>, а с &quot;::&quot; я справлюсь, но проверять то надо.</p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;Вот общий код, который далёк от идеала.</div><div class="fancy_spoiler"><div class="codebox"><pre><code>;Тут только OK
  сMsgBoxInfo_Ok          :=0+8192+64 ;only an OK button + Task Modal + Icon Asterisk(info)
  сMsgBoxError_Ok         :=0+8192+16 ;only an OK button + Task Modal + Icon Hand (stop/error)  
  сMsgBoxChoice_Ok        :=0+8192+48 ;only an OK button + Task Modal + Icon Exclamation
;Тут Yes/No(Да/Нет) 
  сMsgBoxQuest_YN         :=4+8192+32 ;Yes/No button  + Task Modal + Icon Question
  сMsgBoxInfo_YN          :=4+8192+64 ;Yes/No button + Task Modal +  Icon Asterisk (info)
;Тут OK/Cansel(Да/Отмена)
  сMsgBoxInfo_OK_Cansel   :=1+8192+64 ;OK/Cansel button + Task Modal +  Icon Asterisk (info)
  сMsgBoxChoice_OK_Cansel :=1+8192+48 ;OK/Cansel button + Task Modal + Icon Exclamation
  сMsgBoxQuest_OK_Cansel  :=1+8192+32 ;OK/Cansel button  + Task Modal + Icon Question
  

;Общие определения
; Пропуск - тут много...

; Сокращения и сообщения
cNoLbL  := &quot;lNoLabel&quot; ; Метка-заглушка для вывода справки и просто так
cOnHK      := &quot;ON&quot; 
cOffHK     := &quot;OFF&quot;

; Только для Hotkey и не печатаемые символы
cCrushMore    := &quot;~&quot; ; для сочетаний типа Ctrl+Win+10 надо добавить (cCrush)+Ctrl+Win+10
cCrush2       := &quot;*&quot;
cCrush3       := &quot;@&quot;
cCrushItself  := &quot;$&quot;
cCrushAnd     := &quot;&amp;&quot;
cCrushAndSPS  := &quot; &amp; &quot;


;Акронимы и клавиши модификаторы
cMenuWin    := &quot;AppsKey&quot;
cRWin       := &quot;RWin&quot;
cLWin       := &quot;LWin&quot; 
cCtrl       := &quot;Ctrl&quot;
cRCtrl      := &quot;RCtrl&quot;
cLCtrl      := &quot;LCtrl&quot;
cShift      := &quot;Shift&quot;
cRShift     := &quot;RShift&quot;
cLShift     := &quot;LShift&quot;
cAlt        := &quot;Alt&quot;
cRAlt       := &quot;RAlt&quot;
cLAlt       := &quot;LAlt&quot;

iAsKeyName        := 1  ; индекс имени
iAsKeyAcronym     := 2  ; индекс акронима
arAssigKey        :=[[cMenuWin,cMenuWin]
                    ,[cRWin,cRWin], [cLWin,cLWin]
                    ,[cCtrl,&quot;^&quot;], [cRCtrl,&quot;&gt;^&quot;],[cLCtrl,&quot;&lt;^&quot;]
                    ,[cShift,&quot;+&quot;],[cRShift,&quot;&gt;+&quot;],[cLShift,&quot;&lt;+&quot;]
                    ,[cAlt,&quot;!&quot;],  [cRAlt,&quot;&gt;!&quot;],  [cLAlt,&quot;&lt;!&quot;]]

;----------------fnHotkey = основная функция генерации Hotkey--------------------------------------------
;На вход
;1-й Переменная это строка из INI содержащая клавиши не более трёх
;2-й Метка - она должна быть
;3-й Включит/выключить True/False. Включить по умолчанию
;4-й Проверять(по умолчанию) или не проверять. Рекомендуется не отключать, что бы избежать конфликтов.

;На выход 
;Имя горячей клавиши(строка) ,а при ошибке авто-отработка и выход.
;Выходит без проверки и действий при BaseHotkeyFS  := False
fnHotkey(varKeyIn, varLabelIn, varStatusIn:=True, varСheckHotkeyIn:=True)
{
Global ;The directive &quot;global&quot; - should not be an empty string.

;Глобальные константы для справки
;cCrushItself - &quot;$&quot; Когда надо вызывать ту же клавишу внутри её вызова
;cCrushMore   - это для 2-х и 3-х. Дополнить Hotkey &quot;~&quot;, т.е. ~Ctrl &amp; Win $10 (~^#10) что бы обойти левые и правые модификаторы
;cCrushAndSPS - это &quot; &amp; &quot;

;Локальные для этой функции переменные(меняются), константы и массивы
Local i, j, iLoop, jLoop
Local vHotKeyWork, cMaxArHotKeyStr, arHotKeyStr, cMaxArHotKeyAsg, arHotKeyAsg, сHotKeyStrErr
;Thread, NoTimers
  If (!BaseHotkeyFS) ; Ещё читается INI
            Goto  lFnHotkeyExit
  if (!StrLen(varKeyIn)) ; Проверка на пустые Hotkey клавиши
            Goto  lFnHotkeyExit
;Инициализация констант, переменных, массивов - это обязательно
  i :=  0, j :=  0, iLoop :=  0, jLoop :=  0
  vHotKeyWork :=  &quot;&quot;, cMaxArHotKeyStr :=  0,  arHotKeyStr :=  [], cMaxArHotKeyAsg :=  0,  arHotKeyAsg :=  [], сHotKeyStrErr :=  &quot;&quot;

;------Начинаем работу------

;Расчёт и генерация строк и акнонимов, а так же сHotKeyStrErr если будет ошибка для Hotkey  
  arHotKeyStr     :=  fnParseSPS(varKeyIn)    ;Массив для текста клавиш - они нужны для построения акронимов
  cMaxArHotKeyStr :=  arHotKeyStr.MaxIndex()  ;Расчёт длины, т.е. числа клавиш
  i := 0
  Loop %cMaxArHotKeyStr%
    {
      i++
      arHotKeyAsg[i]  :=  fnAssigKey(arHotKeyStr[i])
    }
  cMaxArHotKeyAsg :=  arHotKeyAsg.MaxIndex()
  
;Построение сочетания клавиш для Hotkey(vHotKeyWork) и генерация строки клавиш для ошибки(сHotKeyStrErr)
  i :=  0,  vHotKeyWork :=  &quot;&quot;,  сHotKeyStrErr :=  &quot;&quot;
  Loop %cMaxArHotKeyAsg%
    {
      i++
      If (i = 1)
            сHotKeyStrErr :=  arHotKeyStr[i]
          Else
            сHotKeyStrErr :=  сHotKeyStrErr cCrushAndSPS arHotKeyStr[i]
      vHotKeyWork :=  vHotKeyWork arHotKeyAsg[i]
    }
   
  HotKey %vHotKeyWork%, %varLabelIn%, %cOffHK%, UseErrorLevel  ; Включение HotKey
  MyErrorLevel := ErrorLevel
  If (MyErrorLevel != 0)
    {
        сHotKeyStrErr := &quot;HotKey&quot; cSps сHotKeyStrErr cComma cSps varLabelIn 
      If (MyErrorLevel = 1)
            Error_TXT := &quot;В параметре Label указано несуществующее имя метки.&quot;
      If (MyErrorLevel = 2)
            Error_TXT := &quot;Дубликат горячих клавиш или они не поддерживаются системой.&quot;
      If (MyErrorLevel = 3)
            Error_TXT := &quot;Неподдерживаемый модификатор горячей клавиши.&quot;
      If (MyErrorLevel = 4)
            Error_TXT := &quot;Клавиши не пригодны для эмуляции AltTab или ShiftAltTab.&quot;
      If (MyErrorLevel = 5)
            Error_TXT := &quot;Команда пытается изменить несуществующую горячую клавишу.&quot;
      If (MyErrorLevel = 6)
            Error_TXT := &quot;Команда пытается изменить несуществующий вариант существующей горячей клавиши.&quot;
      If (MyErrorLevel = 98)
            Error_TXT := &quot;Создание данной горячей клавиши превысило лимит в 700 горячих клавиш.&quot;
      If (MyErrorLevel = 99)
            Error_TXT := &quot;Недостаточно памяти. Ваша OS нестабильна, требуется очистка и настройка.&quot;

      Gosub lMinWinGameKeys
      cTitle      :=  &quot;Ошибка в HotKey&quot; ;Титул MsgBox
      cMsgErr     :=  &quot;`n Ошибка в определении - &quot; сHotKeyStrErr
      cTxtErrAd1  :=  &quot;`n`n Тип ошибки :&quot;
      cTxtErrAd2  :=  &quot;`n &quot; Error_TXT
      cWait       :=  35
      cTxtErrAd3  :=  &quot;`n`n Выход из программы(Тайм-аут = &quot; cWait &quot; сек).&quot;
      MsgBox % сMsgBoxError_Ok, %cTitle%, %cMsgErr% %cTxtErrAd1% %cTxtErrAd2% %cTxtErrAd3%, %cWait%      
      Gosub lExitTotalKeys
    }
  
  If (varStatusIn)
          HotKey %vHotKeyWork%, %varLabelIn%, %cOnHK%, UseErrorLevel
  
lFnHotkeyExit:
;Thread, NoTimers, false
Return vHotKeyWork
}
;-------------------------------------------------------------------------------------------


;------------------------Функция возврата акронима спец. клавиш--------------------------------
fnAssigKey(KeyIn)
{
 Local i, iLoop, flg
  i := 0, iLoop := 0, flg :=  False
  
  flg   :=  False ;Флаг акронима
  
  iLoop :=  arAssigKey.MaxIndex()
  i     :=  0
  loop %iLoop%
    {
      i++
      if (arAssigKey[i,iAsKeyName] = KeyIn)
          {
            flg  :=  True  ; Нашли акроним
            KeyOut  :=  arAssigKey[i,iAsKeyAcronym], break
          }
   }
  If (flg)
      Return KeyOut ; Акроним нашли, возврат не клавиши, а акронима
    Else
      Return KeyIn ; Акроним не нашли, возврат клавиши, что нам дали на входе
}

;---------------Функция которая убирает пробелы и табуляцию. Возвращает строку сиволов через пробел -------------------
; Если Ar = True то массив,  иначе строка
fnParseSPS(buffer, ar := True)
{
local Arr, i, Row, OutStr
  Arr := [], j := 0, i := 0, Row  := &quot;&quot;, OutStr := &quot;&quot;
  Loop, parse, buffer, &quot; &quot;
    { 
      Row := RegExReplace(A_LoopField, &quot;&quot;&quot;| |&quot; A_Tab)
        If Row is space 
            Continue
      Arr[++i] := Row
    }
  If(ar)
;Возврат массива    
    Return Arr  

;Возврат строки - символы через пробел  
  i := Arr.MaxIndex() 
  Loop %i%
    {
      j++
      ;OutStr  := OutStr Arr[j]
      If (i != j)
          OutStr  := OutStr Arr[j] &quot; &quot;
        Else
          OutStr  := OutStr Arr[j]
    }
Return OutStr
}


Goto leave_FnAr_KES
;----------------------------------Заглушки--------------------------------------------------
;Для ремаппинга клавиш
lPressKeyToMap:
Return

lSentKeyToMap:
Return

;Просто заглушка
lNoLabel: 
Return
;-------------------------------------------------------------------------------------------
leave_FnAr_KES:</code></pre></div></div></div><p> И как работает у меня, может я и не прав, но всё же... лучшего я не придумал. </p><div class="codebox"><pre><code>;--------------Активация/Деактивация функций из INI----------------
BaseHotkeyON:
Thread, NoTimers
Critical 
  fnHotkey(ExitTotalKeys, LabelExitTotalKeys)
; И т.д. 
Critical , Off
Thread, NoTimers, false 
Return

BaseHotkeyOFF:
Thread, NoTimers
Critical
  fnHotkey(ExitTotalKeys, LabelExitTotalKeys, False)
; И т.д. 
Critical , Off
Thread, NoTimers, false 
Return
;----------------------------------------------------------------</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-17T05:25:43Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96498#p96498</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96482#p96482" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Indomito пишет:</cite><blockquote><p>Меня смущает фраза <em>&quot;Hotkey может блокировать или модифицировать переназначение&quot;</em>, т.е. создавать не может?</p></blockquote></div><div class="quotebox"><blockquote><div class="codebox"><pre><code>Hotkey, KeyName [, Label, Options]</code></pre></div><p>…<br />&nbsp; Keyname<br />…<br />When a hotkey is first created -- either by the Hotkey command or a double-colon label in the script -- its key name and the ordering of its modifier symbols becomes the permanent name of that hotkey as reflected by A_ThisHotkey. This name is shared by all variants of the hotkey, and does not change even if the Hotkey command later accesses the hotkey with a different symbol ordering.<br />…</p></blockquote></div>]]></content>
			<author>
				<name><![CDATA[Drugoy]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27463</uri>
			</author>
			<updated>2015-08-16T10:59:35Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96482#p96482</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96480#p96480" />
			<content type="html"><![CDATA[<div class="quotebox"><blockquote><p>A_ThisHotkey это нажатая клавиша, а что посылать мне не известно.</p></blockquote></div><p>Ну а кто кроме вас это должен знать? Конечно по какому принципу AppsKey надо заменять именно на &quot;E&quot;, это всем понятно. </p><p>Может переназначаемые тоже из ини файла берутся?<br />1 переназначается на 2, и наоборот. 3 блокируется.<br /></p><div class="codebox"><pre><code>
 ; только при первом запуске создать файл настроек
IniWrite, *1::2`n*3::`n*2::1, %A_ScriptDir%\HK.ini, keys

in := {}
IniRead, Data, %A_ScriptDir%\HK.ini, keys
Loop, parse, Data, `n   
{ 
    RegExMatch(A_LoopField, &quot;(.*?)::(.*)&quot;, m)
    in[m1] := m2 
    Hotkey, %m1%, remap, useerrorlevel
}
Return

remap: 
    Send % in[A_ThisHotkey]
    Return 
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[serzh82saratov]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27879</uri>
			</author>
			<updated>2015-08-16T09:15:37Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96480#p96480</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96478#p96478" />
			<content type="html"><![CDATA[<p>Посмотри <a href="http://forum.script-coding.com/viewtopic.php?pid=89818#p89818">здесь</a> может найдешь что-то полезное.</p>]]></content>
			<author>
				<name><![CDATA[Alectric]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=26027</uri>
			</author>
			<updated>2015-08-16T08:14:29Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96478#p96478</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96477#p96477" />
			<content type="html"><![CDATA[<p>А вот пока всё выглядит громоздко. </p><div class="codebox"><pre><code>Hotkey AppsKey, lKey_Menu
Return
 
lKey_Menu: ;AppsKey
  If (!fnChkWinKeys(TMP_ThisHotkey))
        Return
  Thread, NoTimers
  Critical
  if (TMP_ThisHotkey = &quot;AppsKey&quot;)
          Send {E}

          ;Далее куча IF

  Critical , Off
  Thread, NoTimers, false
Return

fnChkWinKeys(ByRef TMP_ThisHotkey)
{
  TMP_ThisHotkey  := A_ThisHotkey  
  ;SetTitleMatchMode, 1
  ;If  ((fExtKeys) &amp;&amp; (WinActive(WinNameCame)))
          Return True
  ;      Else
  ;        Return False
}</code></pre></div><p> Всё бы ничего, но нужно создавать массив для работы <strong>SEND</strong>, т.к. A_ThisHotkey это нажатая клавиша, а что посылать мне не известно.</p><br /><p>P.S. Это фрагмент, комментарии поставлены так, что бы он работал.</p>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-16T03:50:04Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96477#p96477</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Как реализовать remapping клавиш средствами HotKey]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=96476#p96476" />
			<content type="html"><![CDATA[<p>В статическом варианте это выглядит так.<br /><strong>ИсходнаяКлавиша::КонечнаяКлавиша</strong></p><p>Но я не могу описать все клавиши, т.к. идёт инициализация из INI-файла.</p><p>Я долго мучал <strong>HotKey</strong> и на 20-30 варианте записи сдался, просто не могу понять что надо написать.</p><p>Или это нельзя сделать?</p><p>Хотя вот справка </p><div class="quotebox"><blockquote><p>Подобным образом команда Hotkey может блокировать или модифицировать переназначение. Например, следующие две команды будут блокировать переназначение. <br /></p><div class="codebox"><pre><code>a::b
Hotkey, *a, off
Hotkey, *a up, off
Return
</code></pre></div></blockquote></div><p> Все работает, но только при <strong>a::b</strong>, вот как отдельно переназначить не понятно.</p><p>Меня смущает фраза <em>&quot;Hotkey может блокировать или модифицировать переназначение&quot;</em>, т.е. создавать не может?</p>]]></content>
			<author>
				<name><![CDATA[Indomito]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27285</uri>
			</author>
			<updated>2015-08-16T03:15:23Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=96476#p96476</id>
		</entry>
</feed>
