Alectric Спасибо - гляну.
Drugoy Да, я читал это, но подумал... мало ли есть метод.
serzh82saratov Я сначала и не понял что ты сделал/написал, но когда начал разбираться то понял.
;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