Я подражаю еще одной жертве хаоса в раскладке клавиатуры, которая страдает от похожей, но немного другой проблемы.
Я активно использую немецкую и русскую раскладки клавиатуры на своей рабочей станции Windows 10 и часто переключаюсь между ними. Проблема связана с тем, что буквы Y и Z поменялись местами в немецкой раскладке клавиатуры по сравнению со стандартной английской раскладкой QWERTY.
Если я использую немецкую раскладку, то клавиша «Отменить» (Ctrl-Z) привязана к клавише Z, которая расположена в середине первого ряда букв между T и U. Клавиша «Вернуть» (Ctrl-Y) привязана к клавише Y, которая расположена слева от X в нижнем ряду букв немецкой раскладки QWERTZ.
Если переключить раскладку на русскую, то внезапно происходит нечто ужасное. Сочетания клавиш Undo и Redo взаимно меняют свое положение на клавиатуре. Undo (Ctrl-Z) теперь находится на Y (нижний ряд, слева от X), а Redo на Z (верхний ряд, между T и U). Это расположение идентично расположению Ctrl-Z и Ctrl-Y на стандартной английской раскладке клавиатуры.
Это означает, что расположение клавиш Undo и Redo меняется на противоположное каждый раз, когда я переключаю раскладку клавиатуры. Как вы можете себе представить, я всегда нажимаю не ту клавишу, потому что невозможно выучить два колебательных противоположных шаблона, по крайней мере, мой спинной мозг протестует. Поскольку я очень часто использую клавиши Undo и Redo, такое поведение меня очень раздражает.
Я хочу исправить физическое расположение (клавиш) сочетаний клавиш «Повторить» и «Отменить» во всем наборе приложений Windows на немецкую или, лучше, на английскую раскладку.
Постоянное использование английской раскладки для всех видов текстов на основе латиницы хотя и решает проблему с переходом к сочетаниям клавиш «Отменить»/«Повторить», но для меня это не вариант, поскольку мне нужно набирать немецкие тексты со всеми умлаутами и ß (не предлагайте международную раскладку для ввода диакритических знаков, поскольку немецкий — мой основной язык, и я хочу набирать его родные буквы одним нажатием клавиши).
Как уже упомянул коллега в упомянутом вопросе, в Интернете нет очевидного ответа. Та же проблема решается в Ubuntu путем создания пользовательской раскладки клавиатуры. Я не могу найти никакой информации о создании пользовательской раскладки для Windows или исправлении текущей.
Такое поведение характерно для всех известных мне версий Windows и тесно связано с первоначальными раскладками клавиатуры, которые просто несовместимы с пользователями, использующими немецко-русскую языковую пару, как я.
Хорошее решение должно быть реализовано в Windows напрямую без дополнительного ПО или только с открытым исходным кодом. Рабочие решения с использованием AutoHotKey приветствуются.
С помощью @miroxlav я придумал этот полурабочий скрипт AHK:
; Undo
$^z::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070409) ; revert undo-redo hotkey mapping if in German layout
Send ^y
Else
Send ^н ; pass the keystroke through
Return
; Redo
$^y::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070409) ; revert undo-redo hotkey mapping if in German layout
Send ^z
Else
Send ^я ; pass the keystroke through
Return
Этот скрипт идеально переназначает Ctrl-Y <-> Ctrl-Z на немецкой раскладке, но портит обе горячие клавиши на русской раскладке. Я использую ^н и ^я в надежде эмулировать эквиваленты скан-кода Ctrl-Y или Ctrl-Z для русской раскладки, но это не работает (генерирует н для Ctrl-Y и ничего видимого для Ctrl-Z). Использование ^z и ^y для русской раскладки тоже не работает, генерируя буквы z и y соответственно.
В отличие от ответа Miroxlav мне пришлось использовать клавиатурный хук ($), чтобы избежать зацикливания и удалить метки (вероятно, ошибка копирования и вставки)
Решение, предложенное Уильямсом:
^SC02c::Send ^y
^SC015::Send ^z
к сожалению, тоже не работает. Он генерирует простые буквы 'y' и 'z' на русской раскладке и никаких изменений на немецкой раскладке (Ctrl-Z и Ctrl-Y пропускаются в исходном отображении).
Все еще ищу решение.
решение1
Вы можете просто создать свою собственную раскладку клавиатуры, используяMicrosoft Keyboard Layout Creator 1.4 из официального центра загрузки Microsoft.
На YouTube есть множество видеоуроков по его использованию (например,этотс русской локалью) - просто найдите ее название. Но по сути, вы клонируете одну из существующих раскладок клавиатуры и изменяете ее в соответствии со своими потребностями.
Решение AutoHotKey:
(примечание: замените 0x4090409
константу (клавиатура США) на значение, которое применимо к вашей раскладке)
$^z::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4090409)
Send ^z
Else
Send ^y
Return
$^y::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4090409)
Send ^y
Else
Send ^z
Return
Хук ($) необходим для избежания рекурсии, т.е. Send ^z
вызова Send ^y
еще одного макроса AHK.
Я протестировал это условие обнаружения клавиатуры, оно работало отлично.
Конечно, можно реализовать функцию обнаружения клавиатуры и, таким образом, оптимизировать код и т. д. Мне было лень это делать. :)
решение2
Я наконец нашел работающее решение для себя (скрипт AutoHotKey):
; Undo Ctrl-Z
^sc02C::
Send, ^{sc015}
Return
; Redo Ctrl-Y
^sc015::
Send, ^{sc02C}
Return
Он идеально сохраняет клавишу отмены (Ctrl-Z) на ее логическом месте — в нижнем левом ряду — независимо от раскладки клавиатуры.
Спасибо @Miroxlav и @Williams за предоставленные материалы для решения проблемы.
решение3
На основе ответа Антона я обновил код до AHK v2 и добавил поддержку варианта Ctrl+Shift, так как многие программы теперь используют его для Redo.
#Requires AutoHotkey v2.0
;Remapping upper mid Y/Z key (Y in EN layout)
^sc015::Send "^{sc02C}"
^+sc015::Send "^+{sc02C}"
;Remapping lower left Y/Z key (Z in EN layout)
^sc02C::Send "^{sc015}"
^+sc02C::Send "^+{sc015}"
Цель этого скрипта — закрепить действие «Отменить» за нижней левой клавишей Y/Z, поскольку разные раскладки (QWERTZ и QWERTY) перемещают Z в верхнюю середину, что непрактично. То же самое касается и «Повторить», которая теперь закреплена за верхней серединой клавиши Y/Z.
Так как Undo/Redo обычно выполняются с помощью Ctrl+Z/Y, этого можно добиться, захватив нажатую клавишу и повторно вызвав "правильную" клавишу. Это строки ^sc0**
. ^+sc0**
Строки предназначены для повторной генерации событий Ctrl+Shift+Z/Y, так как многие программы используют Ctrl+Shift+Z для Redo.
"Правильный" ключ в кавычках, потому что если посмотреть на скрипт, то на самом деле это должно быть просто переключение Ctrl(+Shift)+Y/Z везде... и, следовательно, ничего не происходит. Однако это не то, что происходит, и это просто работает... хотя я и, насколько мне известно, оригинальный автор не знаем, почему.
Если у вас есть какие-либо соображения о том, почему это работает или не работает для вас... сообщите нам об этом.
решение4
Несмотря на то, что принятый ответ работает, он работает только в том случае, если выбранной раскладкой в тот момент была немецкая раскладка, в противном случае он переворачивает функцию отмены во всех других раскладках.
Чтобы решить эту проблему, вам просто нужно заменить код США 0x4090409
на код Германии 0x4070407
. Также вам нужно изменить оператор if следующим образом:
$^z::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070407)
Send ^y
Else
Send ^z
Return
$^y::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070407)
Send ^z
Else
Send ^y
Return