Windows에서 독일어와 러시아어 키보드 레이아웃 간의 실행 취소(Ctrl-Z) 및 다시 실행(Ctrl-Y) 단축키의 물리적 위치 수정

Windows에서 독일어와 러시아어 키보드 레이아웃 간의 실행 취소(Ctrl-Z) 및 다시 실행(Ctrl-Y) 단축키의 물리적 위치 수정

나는 유사하지만 약간 다른 문제로 고통받는 키보드 레이아웃 혼란의 또 다른 희생자를 모방하고 있습니다.

저는 Windows 10 워크스테이션에서 독일어와 러시아어 키보드 레이아웃을 광범위하게 사용하고 있으며 자주 전환합니다. 문제는 표준 영어 QWERTY 레이아웃과 비교하여 독일어 키보드 레이아웃에서 문자 Y와 Z가 전환된다는 사실과 관련이 있습니다.

독일어 레이아웃을 사용하는 경우 실행 취소 단축키(Ctrl-Z)는 T와 U 사이의 첫 번째 문자 행 중간에 있는 키 Z에 바인딩됩니다. 다시 실행(Ctrl-Y)은 키 Y에 바인딩됩니다. , 이는 독일 QWERTZ 레이아웃에서 낮은 문자 행의 X 왼쪽에 있습니다.

레이아웃을 러시아어로 전환하면 갑자기 나쁜 일이 발생합니다. 실행 취소 및 다시 실행 단축키는 키보드에서 위치를 상호 변경합니다. 실행 취소(Ctrl-Z)는 이제 Y(하단 행, 왼쪽에서 X)에 있고 다시 실행은 Z(상단 행, T와 U 사이)에 있습니다. 이 위치는 표준 영어 키보드 레이아웃의 Ctrl-Z 및 Ctrl-Y 위치와 동일합니다.

즉, 키보드 레이아웃을 전환할 때마다 실행 취소 및 다시 실행 단축키의 위치가 반대 방향으로 변경된다는 의미입니다. 당신이 상상할 수 있듯이 나는 항상 잘못된 지름길을 누르고 있습니다. 왜냐하면 두 개의 진동하는 반대 패턴을 배우는 것이 불가능하기 때문입니다. 적어도 내 척추 뇌는 항의합니다. 나는 실행 취소 및 다시 실행 단축키를 매우 자주 사용하기 때문에 이 동작은 나를 많이 짜증나게 합니다.

전체 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 답변과 다르게 반복을 방지하고 레이블을 제거하기 위해 키보드 후크($)를 사용해야 했습니다(아마도 복사 붙여넣기 실수일 수 있음)

Williams가 제안한 솔루션:

^SC02c::Send ^y
^SC015::Send ^z

불행히도 작동하지 않습니다. 러시아어 레이아웃에서는 일반 문자 'y' 및 'z'를 생성하고 독일어 레이아웃에서는 변경 사항이 없습니다(원본 매핑에서 Ctrl-Z 및 Ctrl-Y가 전달됨).

아직도 해결책을 찾고 있습니다.

답변1

다음을 사용하여 자신만의 키보드 레이아웃을 만들 수 있습니다.공식 Microsoft 다운로드 센터의 Microsoft Keyboard Layout Creator 1.4.

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

Anton의 답변을 바탕으로 코드를 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를 위쪽 중간으로 이동하기 때문입니다. 이는 비실용적입니다. Redo도 마찬가지입니다. 이제 Redo는 Y/Z 키 상단 중앙에 고정되어 있습니다.

실행 취소/다시 실행은 일반적으로 Ctrl+Z/Y로 수행되므로 누른 키를 캡처하고 "올바른" 키를 다시 내보내면 이를 수행할 수 있습니다. 그것들은 ^sc0**라인입니다. 많은 프로그램이 다시 실행을 위해 Ctrl+Shift+Z를 사용하므로 이 ^+sc0**행은 Ctrl+Shift+Z/Y 이벤트를 다시 발생시키기 위한 것입니다.

"올바른" 키는 따옴표로 묶여 있습니다. 왜냐하면 스크립트를 보면 실제로 어디에서나 Ctrl(+Shift)+Y/Z를 뒤집어야 하기 때문입니다. 따라서 아무 것도 얻지 못합니다. 그러나 그것은 일어나는 일이 아니며 단지 작동합니다... 비록 저와 AFAIK가 원저자가 이유를 모르더라도 말이죠.

이것이 효과가 있거나 효과가 없는 이유에 대한 통찰력이 있는 경우... 목소리를 높여주세요.

답변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

관련 정보