1 (изменено: Indomito, 2015-08-16 07:24:40)

Тема: AHK: Как реализовать remapping клавиш средствами HotKey

В статическом варианте это выглядит так.
ИсходнаяКлавиша::КонечнаяКлавиша

Но я не могу описать все клавиши, т.к. идёт инициализация из INI-файла.

Я долго мучал HotKey и на 20-30 варианте записи сдался, просто не могу понять что надо написать.

Или это нельзя сделать?

Хотя вот справка

Подобным образом команда Hotkey может блокировать или модифицировать переназначение. Например, следующие две команды будут блокировать переназначение.

a::b
Hotkey, *a, off
Hotkey, *a up, off
Return

Все работает, но только при a::b, вот как отдельно переназначить не понятно.

Меня смущает фраза "Hotkey может блокировать или модифицировать переназначение", т.е. создавать не может?

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

2 (изменено: Indomito, 2015-08-16 08:09:22)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

А вот пока всё выглядит громоздко.

Hotkey AppsKey, lKey_Menu
Return
 
lKey_Menu: ;AppsKey
  If (!fnChkWinKeys(TMP_ThisHotkey))
        Return
  Thread, NoTimers
  Critical
  if (TMP_ThisHotkey = "AppsKey")
          Send {E}

          ;Далее куча IF

  Critical , Off
  Thread, NoTimers, false
Return

fnChkWinKeys(ByRef TMP_ThisHotkey)
{
  TMP_ThisHotkey  := A_ThisHotkey  
  ;SetTitleMatchMode, 1
  ;If  ((fExtKeys) && (WinActive(WinNameCame)))
          Return True
  ;      Else
  ;        Return False
}

Всё бы ничего, но нужно создавать массив для работы SEND, т.к. A_ThisHotkey это нажатая клавиша, а что посылать мне не известно.


P.S. Это фрагмент, комментарии поставлены так, что бы он работал.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

3

Re: AHK: Как реализовать remapping клавиш средствами HotKey

Посмотри здесь может найдешь что-то полезное.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

4 (изменено: serzh82saratov, 2015-08-16 13:21:10)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

A_ThisHotkey это нажатая клавиша, а что посылать мне не известно.

Ну а кто кроме вас это должен знать? Конечно по какому принципу AppsKey надо заменять именно на "E", это всем понятно.

Может переназначаемые тоже из ини файла берутся?
1 переназначается на 2, и наоборот. 3 блокируется.


 ; только при первом запуске создать файл настроек
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, "(.*?)::(.*)", m)
    in[m1] := m2 
    Hotkey, %m1%, remap, useerrorlevel
}
Return

remap: 
    Send % in[A_ThisHotkey]
    Return 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5 (изменено: Drugoy, 2015-08-16 15:24:07)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

Indomito пишет:

Меня смущает фраза "Hotkey может блокировать или модифицировать переназначение", т.е. создавать не может?

Hotkey, KeyName [, Label, Options]


  Keyname

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.

6 (изменено: Indomito, 2015-08-17 13:22:07)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

Alectric Спасибо - гляну.

Drugoy Да, я читал это, но подумал... мало ли есть метод.

serzh82saratov Я сначала и не понял что ты сделал/написал, но когда начал разбираться то понял.

+ Написал такой INI, думал не сработает, глупо конечно.
[keys]
+a::E
^s::e
!d::Q
+ А вот код, поставил меня в тупик, то что я не понял - поставил комментарии.
;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, "(.*?)::(.*)", m) ; Тут всё почти понятно, но две строки ниже...
    ar[m1] := m2 ; m1 - индекс, но ниже это Hotkey-клавиша.
    Hotkey, %m1%, remap, useerrorlevel ; Я вот про это, хотя клавиша и есть код, но... т.е. непонятно.
}
Return

remap: 
    Send % ar[A_ThisHotkey] ; А это точно не понятно, адресация по нажатой, это как.
    Return

Мне нужно понимать, что я пишу, иначе я точно запутаюсь - код у меня и так весьма большой за 3к строк перевалил - просто я потом ошибки не найду.

Можешь упростить свой пример или же дашь пояснения?

Уберём чтение и за основу возьмем, скажем, двухмерный массив: ar := [["q","a"],["w","s"]] т.е. пары нажимаемая и посылаемая клавиши.  Повтори, но попроще, для особенно не одарённых, а?

Я сам сделал на основе IF методом перебора в массиве, но твой пример меня на 99% просто убил.

Почему прошу?
У меня до активации каждой клавиши, проверка её на метку заглушку, а потом ещё 3-5 проверок, после чего конвертация управляющих клавиш в акронимы, а уж потом активация на реальную функцию и ещё строится справка в виде GUI-Help, если ошибка, то генерация в чём допущена ошибка и в каком месте INI.

Фрагмент одного из INI-файлов.
Было (исходный текст в INI):

;Безусловный выход
NameExitTotalKeys=Безусловный выход
ExitTotalKeys=~ Ctrl Shift  Esc
LabelExitTotalKeys=lExitTotalKeys

Стало (для работы HotKey): ExitTotalKeys=~^+ESC

P.S. Для справки —  поверка, разборка, активация и деактивация HotKey. Тут почти всё, что относится к HotKey, да, это к моей просьбе не имеет отношения, но активатор у меня один, и если их станет несколько то будет сложно "найти концы", а с "::" я справлюсь, но проверять то надо.

+ Вот общий код, который далёк от идеала.
;Тут только 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  := "lNoLabel" ; Метка-заглушка для вывода справки и просто так
cOnHK      := "ON" 
cOffHK     := "OFF"

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


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

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

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

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

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

;Локальные для этой функции переменные(меняются), константы и массивы
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 :=  "", cMaxArHotKeyStr :=  0,  arHotKeyStr :=  [], cMaxArHotKeyAsg :=  0,  arHotKeyAsg :=  [], сHotKeyStrErr :=  ""

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

;Расчёт и генерация строк и акнонимов, а так же с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 :=  "",  сHotKeyStrErr :=  ""
  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 := "HotKey" cSps сHotKeyStrErr cComma cSps varLabelIn 
      If (MyErrorLevel = 1)
            Error_TXT := "В параметре Label указано несуществующее имя метки."
      If (MyErrorLevel = 2)
            Error_TXT := "Дубликат горячих клавиш или они не поддерживаются системой."
      If (MyErrorLevel = 3)
            Error_TXT := "Неподдерживаемый модификатор горячей клавиши."
      If (MyErrorLevel = 4)
            Error_TXT := "Клавиши не пригодны для эмуляции AltTab или ShiftAltTab."
      If (MyErrorLevel = 5)
            Error_TXT := "Команда пытается изменить несуществующую горячую клавишу."
      If (MyErrorLevel = 6)
            Error_TXT := "Команда пытается изменить несуществующий вариант существующей горячей клавиши."
      If (MyErrorLevel = 98)
            Error_TXT := "Создание данной горячей клавиши превысило лимит в 700 горячих клавиш."
      If (MyErrorLevel = 99)
            Error_TXT := "Недостаточно памяти. Ваша OS нестабильна, требуется очистка и настройка."

      Gosub lMinWinGameKeys
      cTitle      :=  "Ошибка в HotKey" ;Титул MsgBox
      cMsgErr     :=  "`n Ошибка в определении - " сHotKeyStrErr
      cTxtErrAd1  :=  "`n`n Тип ошибки :"
      cTxtErrAd2  :=  "`n " Error_TXT
      cWait       :=  35
      cTxtErrAd3  :=  "`n`n Выход из программы(Тайм-аут = " cWait " сек)."
      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  := "", OutStr := ""
  Loop, parse, buffer, " "
    { 
      Row := RegExReplace(A_LoopField, """| |" 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] " "
        Else
          OutStr  := OutStr Arr[j]
    }
Return OutStr
}


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

lSentKeyToMap:
Return

;Просто заглушка
lNoLabel: 
Return
;-------------------------------------------------------------------------------------------
leave_FnAr_KES:

И как работает у меня, может я и не прав, но всё же... лучшего я не придумал.

;--------------Активация/Деактивация функций из 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
;----------------------------------------------------------------
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

7 (изменено: Indomito, 2015-08-17 12:16:28)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

-del

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

8

Re: AHK: Как реализовать remapping клавиш средствами HotKey

m1 это не индекс а та клавиша которая нажата физически, m2 собственно та клавиша которая будет нажиматься в системе.
А в таком массиве [] работа может быть не только по индексу но и по ключу.

+ пример
A := []
A[b] := "C"
msgbox % A[b]
Indomito пишет:

Уберём чтение и за основу возьмем, скажем, двухмерный массив:

ar := [ ["q","a"] , ["w","s"] ]
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]

for разделяет массив на маленькие массивы.
В этом примере уже идет работа с индексами, а не с ключами.

9 (изменено: Indomito, 2015-08-17 14:16:25)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

yalanne Да, я понял. А по циклу я то сделал, ещё вчера, я про это.

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

А вот как без цикла? Активировать HotKey с :: Что бы убрать проверку - адресация по ключу?

И вот это.

m1 это не индекс а та клавиша которая нажата физически, m2 собственно та клавиша,
 которая будет нажиматься в системе.
А в таком массиве [] работа может быть не только по индексу но и по ключу.

Это не вызовет ошибок или повторов?
Мне не понятно когда индекс, а когда ключ, т.е. нет прямых указаний.

P.S. Знаю что глупый вопрос, просто я так ранее не делал.

UPD

Блин, я же забыл о символических ключах и перепутал их с индексом, правда всё равно путаюсь... надо перечитать справку по массивам.

Позже...
Всё, разобрался, а то в голове путаница была.

ar := [ ["q","+a", "remap"] , ["w","s" "remap"] ]
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
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

10

Re: AHK: Как реализовать remapping клавиш средствами HotKey

; Если вот так добавлять то это индекс. тут просто добаляется цифра в порядке возростания.
test1 := ["A","B","C"]
test1.Insert("D")

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

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

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

msgbox % test3[1]
    . "`n" test3[text]
    
;если клавиша-цифра то возможно собьет индекс.

11 (изменено: Indomito, 2015-08-17 14:29:40)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

yalanne Вроде понял и тут же запутался ;если клавиша-цифра то возможно собьет индекс. Так как надо писать с точки зрения надёжности?
Просто у меня может встретится что угодно, проверить клавишу я могу, но конфликт цифры-клавиши и индекса точно нет.

Этот вариант рабочий или нет, т.е. с оговорками?

ar := [ ["q","+a", "remap"] , ["w","s", "remap1"] ]
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
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

12

Re: AHK: Как реализовать remapping клавиш средствами HotKey

Indomito пишет:

Этот вариант рабочий или нет, т.е. с оговорками?

Ну да рабочий.

13

Re: AHK: Как реализовать remapping клавиш средствами HotKey

yalanne Ещё раз спасибо.
serzh82saratov Спасибо за общее направление.

Думаю, что вопрос закрыт, пошёл переписывать код.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

14 (изменено: yalanne, 2015-08-18 00:16:18)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

Написал функцию для более удобной работы:

Class remapping
{
Static ListLoad_ini := [],    LoadList := [],File_ini
    __New(apply=0,file="HK",Section="keys")
    {    
        ListLoad_ini := [], this.File_ini := A_ScriptDir "\" file ".ini"
        If !FileExist(this.File_ini) 
            FileAppend, % "[" Section "]", % this.File_ini
        IniRead, Data,% this.File_ini, %Section%
        Loop, parse, Data, `n   
            RegExMatch(A_LoopField, "O)(.*?)::(.*)", m),    this.ListLoad_ini.Insert(m)
        if apply
            this.Load()
        return this
    }
    Load(key="all")
    {
        for i,k in this.ListLoad_ini
        if (key="all") or (key=k[1])
        {
            this.LoadList.Insert(k)
            Hotkey, % k[1], pressed, On
        }
        return this    
    }
    Save(Section="keys")
    {
        FileDelete % this.File_ini
        for i,k in this.LoadList
            IniWrite,% k[1] "::" 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="all")
    {
        loop % this.LoadList.MaxIndex()
        {
            if (key1="all") 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
    }
}

Отступив пару строчек вниз пишем RG := new remapping(Options)
В этой функции есть 3 параметра:

  • 0 - Загружает в память настройки из ini файла\1 - загружает и применяет. По Умолчанию 0

  • Имя файла настроек(без расширения .ini) По умолчанию HK

  • Имя секции в файле настроек. По умолчанию Keys

Если просто написать RG := new remapping(1), то скрипт просто загрузит и применит клавиши, оставив настройки загрузки по стандарту.

Функция  RG.Load() аналог первого параметра из первой функции. Применяет клавиши. Отличие от первого варианта то, что можно указать конкретную клавишу вместо всего что есть в списке.(если функция пуста загружает все)
Пример для загрузки кнопки A из ini RG.Load("A")

Дальше идет функция RG.Add(key1,key2) она служит для добавления клавиш( не сохраняет в ini. для сохранения есть отдельная функция)

Функция RG.Remove(key1) удаляет из списка клавишу, если не указанна клавиша стирает все.

Для редактирования есть функция RG.Edit(key1,key2).

Ну и пока что последняя функция это сохранения RG.Save()

p.s все key указываются в кавычках ""

15 (изменено: Indomito, 2015-08-18 13:29:35)

Re: AHK: Как реализовать remapping клавиш средствами HotKey

yalanne Спасибо, правда открыв пост и почитал бегло не очень понял.

Перечитал - понял, но у меня лично, она не будет работать - надо её переписывать, но у меня.
1. Чтение и запись INI-файлов это функция.
2.  Hotkey у меня функция и делает больше чем просто назначение - генерация справки в GUI и т.д.

P.S. Спасибо ещё раз и как пример. 

+ Чтение INI в виде функции (моя реализация)
;---------------------------Чтение и проверка INI-файла--------------------------------------------

fnIniReadAndСheck(ByRef OutputINI, FilenameINI, SectionINI := "", KeyINI := ""
                  , 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) && (OutputINI != "ERROR"))
            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 = "ERROR") && (SkipSec || SkipVar)) ; У секции более высокий приоритет, если SkipSec = SkipVar = True
        {
          If (SkipSec)
                OutputINI := SectionINI
            Else If (SkipSec) (SkipSec)
                OutputINI := SectionINI                
          Return False
         }
         
  ; Пропуск Переменной в Секции при ошибке
  If ((OutputINI = "ERROR") && SkipVar)
        {
          OutputINI := SectionINI
          Return False
         }
         
  If (OutputINI = "ERROR") ; Ошибка отсутствует Секция и/или Переменная
        {
          
          NumError := 2
          fnIniErrorOut(NumError := 2, FilenameINI, SectionINI,  KeyINI, vWait) ; не верная переменная или секция
          Return
        }
}
;--------------------------------------------------------------------------------------------

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


  If (NumError = 0)
        {
          fnIniErrorOut_LabelMin  := "ErrorOutMin"
          fnIniErrorOut_LabelExit := "ErrorOutExit"
          ;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 :=  [" Отсутствует INI-файл"                                        ; = 1
                    ," В имени переменной/её нет/ошибка в имени секции."            ; = 2
                    ," Переменная не может быть пустой."                            ; = 3
                    ," Переменная содержит недопустимое значение."                  ; = 4
                    ," Переменная должна быть числом."                              ; = 5
                    ," Переменная должна быть целым числом."                        ; = 6
                    ," Переменная должна быть числом с плавающей точкой."           ; = 7
                    ," Переменная меньше допустимого значения и не число."          ; = 8
                    ," Переменная больше допустимого значения и не число."          ; = 9
                    ," Переменная  вне допустимого диапазона или не число."         ; = 10
                    ," Переменная содержит не верный путь и/или программу."         ; = 11
                    ," Переменная содержит не верный путь."                         ; = 12
                    ," Переменная не число, ни целое/ни с плавающей точкой."        ; = 13
                    ," Резерв или ошибка в программе."                              ; = 14
                    ," Резерв или ошибка в программе."                              ; = 15
                    ," Резерв или ошибка в программе."                              ; = 16
                    ," Резерв или ошибка в программе."                              ; = 17
                    ," Резерв или ошибка в программе."                              ; = 18
                    ," Резерв или ошибка в программе."                              ; = 19
                    ," Резерв или ошибка в программе."                              ; = 20
                    ," Резерв или ошибка в программе."                              ; = 21
                    ," Резерв или ошибка в программе."]                             ; = 22

  Error_TXT :=  arIniErrorTXT[NumError]
  cWait :=  SecWait
  Gosub %fnIniErrorOut_LabelMin%
    cTitle      :=  "`n`n Ошибка в INI-файле" ;Титул MsgBox
    cMsgErr     :=  "                                 ОШИБКА В INI-ФАЙЛЕ`n`n  ->>" Error_TXT
    cTxtErrAd1  :=  "`n`n Файл : " FilenameINI
    cTxtErrAd2  :=  "`n Секция = [" SectionINI "] `n Ключ = " KeyINI
    ;cWait       :=  35
    cTxtErrAd3  :=  "`n`n Выход из программы(Тайм-аут = " cWait " сек)."
      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
}
;--------------------------------------------------------------------------------------------
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download