В общем, дело в том, что NumLock+AltShift == Alt.
А комбинация Alt+Num-цифры служит для ввода символа по коду.
И тут меня больше всего заинтересовал тот факт, что значение, возвращаемое far.InputRecordToName() зависит не от её аргумента.
Выше под спойлером можно увидеть для каждой клавиши наборы VK+FarName+InputRecord.
Исходя из InputRecord нажатие HOME должно быть распознано как AltNum7, но функция возвращает nil
Зато по InputRecord, соответствующему отпусканию Alt, функция возвращает символ с кодом 7.
Last edited by John Doe on Thu 28 Sep, 2017 22:14, edited 1 time in total.
sToLp wrote: ↑Thu 28 Sep, 2017 19:37И совершенно не могу понять, почему CtrlAltShiftNum3 и CtrlAltShiftNum9 при выключенном NumLock не опознаются.
У меня распознаются. Ваш макрос не пробовал, просто запустил waitkey.
1) фантастика! по запуску waitkey из комстроки у меня тоже распознаются;
2) попробовал макросом в Win7x32 — при загрузке Far`а не загрузились несколько плагинов, со ссылкой на нехватку тех или иных DLL`ок, а вот клавиши распознались;
3) попробовал макросом в свежеустановленной Win10x64, но ещё до добавления в систему набора DLL-библиотек — повторилась практически та же история, что и в семёрке; и тогда я предположил: то ли у меня в системе какая-то библиотека чудит, то ли плагин какой-то мешается;
4) а поскольку плагин вычислить значительно проще, чем библиотеку, то решил сначала поискать виновника среди плагинов; и нашёл-таки; позор на мою седую голову — им оказался ConEmu; а я ему так доверял! и за многие годы никогда раньше не встречал, чтобы для набора внутренних команд ConEmu или для вызова его макросов применялись какие-либо нампадовские клавиши; и вот надо же — где то, похоже, зашкерились-таки.
Macro {
area="Common"; key="Shift";
condition=function()
local key = mf.waitkey(1)
if key~="" then
mf.postmacro(far.Show("Shift+"..key))
return 100
end
end;
action=function() end;
}
local NumLock,get = 0,-1
local busy
Macro { description="Shift-<NumPad> heuristics";
area="Common"; key="/Num[\\dD].*/";
id="2EB425EA-751B-431F-8DD8-25E82F3F2C28";
condition=function()
return not busy and 0~=band(1,mf.flock(NumLock,get)) and 100
end;
action=function()
local key = mf.akey(1,1)
if -2==mf.eval("Shift"..key,2) then
busy = true
if -2==mf.eval(key,2) then
Keys(key)
end
busy = false
end
end;
}
John Doe wrote: ↑Tue 26 Sep, 2017 13:11Но можно применить эвристику из Far 1.75:
Macro {
area="Shell"; key="/(Shift)|(ShiftNum[0-9])|(ShiftClear)/";
action=function()
local key2 = mf.waitkey(1)
local key = a=="" and akey(1,0) or "Shift"..key2.." (NumLock)"
far.Show(key)
end;
}
. И поэтому осваивал я их по большей части тем способом, что перенимал из них отдельные блоки и пробовал применять эти блоки в своих экспериментах. А о тех результатах данных опытов, которые представляются мне достоверными, изложу здесь далее. Предположительно, тремя частями.
1) Когда, при включённом NumLock, команда lua: far.Show(mf.waitkey(),mf.waitkey(1)) запускается из комстроки, то на выходе мы получаем нажатый шорткат, разделённый на два аргумента. Например:
Macro { area="Shell";
key="Shift ShiftNum7"; -- если первый Shift из поля убрать, то макрос не запустится
action=function()
far.Show(mf.waitkey(),mf.waitkey(1))
end;}
sToLp wrote: ↑Sat 30 Sep, 2017 21:37Но, будучи, при том же условии, запущенной из макроса, far.Show(mf.waitkey(),mf.waitkey(1)) выдаёт нам только вторую часть нажатого шорката:
Естественно, ведь первую часть "съедает" вызов макроса, он же у вас на Shift.
sToLp wrote: ↑Sat 30 Sep, 2017 21:37Но, будучи, при том же условии, запущенной из макроса, far.Show(mf.waitkey(),mf.waitkey(1)) выдаёт нам только вторую часть нажатого шорката:
Естественно, ведь первую часть "съедает" вызов макроса, он же у вас на Shift.
Однако, если Shift из перечня ключей запуска макроса (поля key) убрать, то макрос совсем не отвечает.
Как же тогда правильно сделать?
Macro {
area="Shell"; key="/(Shift)|(ShiftNum[0-9])|(ShiftClear)/";
action=function()
local key2 = mf.waitkey(1)
local key = a=="" and akey(1,0) or "Shift"..key2.." (NumLock)"
far.Show(key)
end;
}
Об этом макросе я прекрасно помню, поскольку изучал его с большим интересом. Так как он является очень полезным примером того, как макросом показать фактически инициировавший его шорткат. И, вместе с тем, примером впечатляющей лаконичности.
Однако на данный момент теперь уже я акцентирую Ваше внимание не на фактически решённой задаче "как макросом показать шорткат, который нажали". Речь идёт о другой проблеме. А именно о том, как макросом показать то, что "первым приходит отдельно модификатор, а потом уже нажатая клавиша".
Выше я воспроизвёл Ваш пример того, что из комстроки это сделать вполне можно. И далее показал, что из макроса та же самая функция даёт не полный результат. И поставил вопрос как сделать его полным? Извините, что свой новый вопрос я изложил недостаточно понятно. Теперь вот пытаюсь исправить эту свою оплошность.
Macro { area="Shell"; key="CtrlAltN"; id="F1100E7A-C473-45CD-A88B-CCCDF8031CBA";
description="tes&t демонстрация того, что при включенном NumLock первыми приходят отдельно модификаторы Shift[Ctrl][Alt], а потом уже нажатая клавиша NumPad`а (sToLp) CtrlAltN";
action=function() mf.flock(NumLock,1) -- подстрахуем включённость NumLock`а
far.Message("\nЧтобы убедиться в том,\nчто при включенном NumLock\nпервыми приходят отдельно модификаторы Shift[Ctrl][Alt],\nа потом уже нажатая клавиша NumPad`а,\nпрямо сейчас сначала нажмите Enter,\nа затем тестируемое клавишесочетание.\n\n... ","Тест ключей Shift[Ctrl][Alt]-<NumPad>:","")
Keys("l u a : f a r . S h o w ( m f . w a i t k e y ( ) , m f . w a i t k e y ( 1 ) )") exit() end; }
Несколько экзотично, но это, по крайней мере, работает.
И здесь ещё нужно уточнить, что отдельно приходят не "модификаторы и клавиша", а "модификаторы и клавиша с модификаторами без Shift`а".
local F = far.Flags
Macro {
area="Common"; key="Num7 ShiftNum7";
action=function()
far.Message("Press key","","")
local key0 = mf.waitkey()
if band(1,mf.flock(0,-1))~=0 then
local key,key2 = mf.waitkey(),mf.waitkey(1)
if key2=="" then
key,key2 = key0,key
end
far.Show(key,key2)
else
far.Show(key0)
end
end;
}
P.S.
Напоминаю, что эта эвристика основана на недокументированных особенностях, зависящих от версии Windows.
Нет гарантии, что с очередным обновлением Windows ничего не поломается (в частности в Windows XP всё иначе).
А единственный надёжный способ это не назначать этот диагностический макрос на Shift<NumPad>, и перед запросом клавиши погасить NumLock (ваша собственная идея).
Текст макроса уже приведён в соответствующей теме http://forum.farmanager.com/viewtopic.p ... 75#p145975.
sToLp wrote: ↑Sun 01 Oct, 2017 09:40Увы, нет. Тогда тот макрос не будет работать.
Чтобы надёжно работало надо исключить или Shift (например Num7) или NumPad (например ShiftSpace).
В таких то случаях, разумеется, что будет работать.
Но в этой теме рассматривается не привычный, а особый случай с NumPad`овскими клавишами-цифрами в сочетаниях с модификаторами экстравагантного поведения. Один из которых — Alt и сам по себе (независимо от состояния NumLock), и совместно с Shift`ом (при горящем NumLock) работает абсолютно особым образом. А другой — Shift, и того похлеще, при взаимодействии с NumPad`овскими цифрами при горящем NumLock от системы как бы и вовсе прячется.
И мне бы желательно не просто знать о том, как взаимодействуют эти клавиши-фокусники, а и уметь это знание правильно излагать. Так, чтобы и другому человеку было понятно о чём идёт речь и почему это именно так. И поэтому для полноты картины ещё очень желательно иметь навык правильно производить манипуляции с NumPad`овскими клавишами-цифрами и быть в состоянии эти действия более-менее грамотно воспроизводить макросами. И я Вам очень благодарен за то, что Вы мне во всём этом эффективно содействуете.
John Doe wrote: ↑Sun 01 Oct, 2017 11:03Нет, можно конечно сделать, чтобы работало и с Shift<NumPad>
local F = far.Flags
Macro {
area="Common"; key="Num7 ShiftNum7";
action=function()
far.Message("Press key","","")
local key0 = mf.waitkey()
if band(1,mf.flock(0,-1))~=0 then
local key,key2 = mf.waitkey(),mf.waitkey(1)
if key2=="" then
key,key2 = key0,key
end
far.Show(key,key2)
else
far.Show(key0)
end
end;
}
, но не стоит всё усложнять.
Просто превосходно!
Что же касается некоторого усложнения макроса, то, на мой взгляд, оно в данном случае вовсе не искусственное, а вполне соответствующее случаю. И как раз облегчающее иллюстрирование сложного и даже можно сказать запутанного случая. При том, что код этого макроса получился у Вас, по-моему, как раз весьма лаконичным.
John Doe wrote: ↑Sun 01 Oct, 2017 12:29P.S.
Напоминаю, что эта эвристика основана на недокументированных особенностях, зависящих от версии Windows.
Нет гарантии, что с очередным обновлением Windows ничего не поломается (в частности в Windows XP всё иначе).
Благодарю Вас за предупреждение! Но что будет с новыми версиями Windows одному Microsoft`у известно. А XP в нашей, например, "фирме" уже нет ни одной.
John Doe wrote: ↑Sun 01 Oct, 2017 12:29А единственный надёжный способ это не назначать этот диагностический макрос на Shift<NumPad>, и перед запросом клавиши погасить NumLock (ваша собственная идея).
Текст макроса уже приведён в соответствующей теме http://forum.farmanager.com/viewtopic.p ... 75#p145975.
Большое спасибо! Как только вполне завершу с этой темой (по ней у меня остались ещё два не до конца исследованных момента) и выпадет относительно свободное время, продолжу и с той темой.
sToLp wrote: ↑Sat 30 Sep, 2017 21:37А о тех результатах данных опытов, которые представляются мне достоверными, изложу здесь далее. Предположительно, тремя частями.
Однако оба неясных для меня до сегодняшнего дня момента благополучно прояснились. Один — как правильно инициировать макросы с Shift-<NumPad>-ключами и другой — о перспективах применения в этих макросах функции akey(). Причём оба эти вопроса сошлись в одном примере. Поэтому завершающей будет вторая часть изложения результатов опытов с этими ключами. Как я их на текущий момент понимаю.
2) "Макросы Shift-<NumPad>" — так для удобства далее здесь буду обозначать макросы, назначаемые на шорткаты, состоящие из клавиш-цифр NumPad`а и модификаторов, в составе которых модификатор Shift.
Опыты показали, что в поле key (т.е. в перечень ключей, запускающих макрос) данных макросов можно дополнительно включать соответствующие "голые" модификаторы (Shift, CtrlShift, AltShift, CtrlAltShift). И тогда данные Shift-<NumPad>-макросы активируются ключами [Ctrl][Alt]ShiftNum#, которыми, казалось бы, они и без дополнений должны были бы активироваться. Но если в поле key оставить только [Ctrl][Alt]ShiftNum#, то эти макросы не запускаются.
Но это дополнительное включение Shift`а приводит к тому большому неудобству, что при наличии других макросов, назначенных на данные "голые" модификаторы, нажатие на них вызывает вывод меню выбора макросов, которые в данном случае фактически-то не имеют отношения к макросам Shift-<NumPad>. Поэтому в таком случае желательно этот дополнительный Shift как ни будь нейтрализовать.
И экспериментально выяснено, что нейтрализовать дополнительные включения Shift, CtrlShift, AltShift и CtrlAltShift в поле key макросов Shift-<NumPad> вроде бы можно с помощью condition подобного следующему.
condition=function()
local key1=mf.waitkey()
return key1~="Shift" -- исключить голый Shift из ключей, вызывающих данный макрос
end;
При этом данный способ совсем не подходит для ранее приведённых четырёх тестовых макросов. Поскольку при включении в них подобного condition результат "первичного" mf.waitkey() далее в тестах проявляться перестаёт. Но в других случаях в макросах Shift-<NumPad> с дублирующим ключом-пустышкой этот condition, по-видимому, применять возможно. Но, вероятно, от таких макросов можно ожидать и разных других сюрпризов.
И поэтому будет гораздо лучше применять предложенный Вами образец составления Shift-<NumPad>-макроса, в котором поле key дополняется не чистым(и) модификатор(ом/ами), а, наоборот, <NumPad>-клавишей (одиночной или с модификаторами Ctrl, Alt или CtrlAlt) без модификатора Shift. И вот опробованный рабочий вариант такого макроса:
Macro { area="Shell"; key="Num7 ShiftNum7";
-- если Num7 из key убрать, то при горящем NumLock макрос не запускается
action=function()
if band(1,mf.flock(0,-1))~=0 then
mf.msgbox("Если NumLock горит:","\nДелаем какое-то действие.",0x00010000)
else
-- при выключенном NumLock при нажатии Num7 эмулируем Home и завершаем макрос:
if mf.akey(1,0)=="Num7" then Keys("Home") exit() end
mf.msgbox("Если NumLock погашен:","Делаем какое-то другое действие.",0x00010000)
end end; }
sToLp wrote: ↑Sun 01 Oct, 2017 16:59Но это дополнительное включение Shift`а приводит к тому большому неудобству, что при наличии других макросов, назначенных на данные "голые" модификаторы, нажатие на них вызывает вывод меню выбора макросов, которые в данном случае фактически-то не имеют отношения к макросам Shift-<NumPad>. Поэтому в таком случае желательно этот дополнительный Shift как ни будь нейтрализовать.
sToLp wrote: ↑Sun 01 Oct, 2017 16:59И поэтому будет гораздо лучше применять предложенный Вами образец составления Shift-<NumPad>-макроса, в котором поле key дополняется не чистым(и) модификатор(ом/ами), а, наоборот, <NumPad>-клавишей (одиночной или с модификаторами Ctrl, Alt или CtrlAlt) без модификатора Shift.
, целенаправленно вызывающем меню выбора макросов.
Результаты нажатий хоткеев фиксировались визуально по обозначению нажимаемой клавиши в заголовке меню выбора макросов и по действию макроса, данным хоткеем инициировавшегося.
Каждая из клавиш NumPad`а вызывает меню выбора макросов, в заголовке которого она обозначена соответствующим образом (совпадающим с результатами выполнения команды lua:far.Show(mf.waitkey()) из комстроки), а исполнение назначенного на клавишу макроса вызывает соответствующую ей штатную команду. Результаты существенно различаются в зависимости от состояния NumLock.
При погашенном NumLock:
Клавиша: Обозначена: Действие:
Num1 Num1 End
Num2 Num2 Down
Num3 Num3 PgDn
Num4 Num4 Left
Num5 Clear "Просмотр файла", на папке – "Вычислить и показать размеры выбранных папок"
Num6 Num6 Right
Num7 Num7 Home
Num8 Num8 Up
Num9 Num9 PgUp
Num0 Num0 Ins / Divide Divide выводит в комстроку прямой слеш "/" * Multiply Multiply исполняет команду "Инвертировать пометку" - Subtract Subtract вызывает меню "Снять" штатной команды "Снять пометку с группы" + Add Add вызывает меню "Пометить" штатной команды "Пометить группу" . (точка) NumDel NumDelключ не задействован внутренней командой Far`а
NumEnter NumEnter исполняет ассоциацию, назначенную на Enter для объекта под курсором
При горящем NumLock:
Клавиша Обозначена Действие
Num1 1 выводит в комстроку цифру 1
Num2 2 выводит в комстроку цифру 2
Num3 3 выводит в комстроку цифру 3
Num4 4 выводит в комстроку цифру 4
Num5 5 выводит в комстроку цифру 5
Num6 6 выводит в комстроку цифру 6
Num7 7 выводит в комстроку цифру 7
Num8 8 выводит в комстроку цифру 8
Num9 9 выводит в комстроку цифру 9
Num0 0 выводит в комстроку цифру 0 / Divide Divide выводит в комстроку прямой слеш "/"; * Multiply Multiply исполняет команду "Инвертировать пометку"; - Subtract Subtract меню "Снять" штатной команды "Снять пометку с группы"; + Add Add меню "Пометить" штатной команды "Пометить группу"; . (точка) NumDel Decimal выводит в комстроку . (точку)
NumEnter NumEnter исполняет ассоциацию, назначенную на Enter для объекта под курсором
Last edited by sToLp on Mon 02 Oct, 2017 22:15, edited 1 time in total.