Карта Capslock для управления в Windows 10

В Windows 8 я использовал переназначение ключа capslock для управления с помощью скрипта реестра

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

После обновления до окна 10 это больше не работает. Как это можно сделать?

12 ответов

Решение

Вы не забыли перезагрузить? Кажется, работает хорошо для меня, так же, как в 7 и 8.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

На случай, если кому-то понадобится сделать это через PowerShell:

$hexified = "00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00".Split(',') | % { "0x$_"};

$kbLayout = 'HKLM:\System\CurrentControlSet\Control\Keyboard Layout';

New-ItemProperty -Path $kbLayout -Name "Scancode Map" -PropertyType Binary -Value ([byte[]]$hexified);

Запустите его от имени администратора и перезагрузите компьютер.

Теперь непосредственно от Microsoft существует решение для сопоставления Caps Lock с управляющей клавишей, которое называется PowerToys . PowerToys не предполагает использование сторонних инструментов или изменение реестра вручную (что может привести к серьезным проблемам, если все сделано неправильно). Инструмент PowerToys, который обрабатывает это, установлен по умолчанию и называется «Диспетчер клавиатуры» . Он работает именно так, как ожидалось — вот изображение клавиши Caps Lock, сопоставленной с клавишей Ctrl.

Вы можете использовать SharpKeys для сопоставления любого ключа с любым другим ключом в Windows 7, 8 или 10. Это гораздо проще и чище, чем изменять реестр самостоятельно.

Надеюсь это поможет.

Я использую следующее, чтобы отправить CTRL для клавиши CAPS LOCK, отправить ALT для клавиши CTRL и отправить CAPS LOCK для клавиши ALT. CTRL находится слева от "A", где Бог и задумал, ALT ниже SHIFT, и совершенно бесполезная клавиша CAPS LOCK надежно спрятана там, где мне нужно сломать запястье, чтобы ударить его.

Windows Registry Editor Version 5.00

; The hex data is in five groups of four bytes:
;   00,00,00,00,\    header version (always 00000000)
;   00,00,00,00,\    header flags (always 00000000)
;   04,00,00,00,\    # of entries (3 in this case) plus a NULL terminator line.
;                    Entries are in 2-byte pairs: Key code to send & keyboard key to send it.
;                    Each entry is in LSB, MSB order.
;   1d,00,3a,00,\    Send LEFT CTRL (0x001d) code when user presses the CAPS LOCK key (0x003a) 
;   38,00,1d,00,\    Send LEFT ALT (0x0038) code when user presses the LEFT CTRL key (0x001d) 
;   3a,00,38,00,\    Send CAPS LOCK (0x3A) code when user presses the LEFT ALT key (0x0038) 
;   00,00,00,00      NULL terminator

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,\
                   00,00,00,00,\
                   04,00,00,00,\
                   1d,00,3a,00,\
                   38,00,1d,00,\
                   3a,00,38,00,\
                   00,00,00,00

Неиссякаемый набор инструментов sysinternals также предоставляет небольшую программу для переключения capslock с помощью control - ctrl2cap.exe.

Я использовал AutoHotKey, чтобы сделать это.

У меня была бы ссылка в каталоге автозагрузки для запуска очень простого ахк-скрипта:

Capslock::Ctrl

Дело в том, что Autohotkey не запускается от имени администратора, поэтому он не влияет на привилегированные окна, если вы не используете планировщик задач вместо каталога запуска для запуска сценария при входе в систему с более высокими привилегиями. Вторая проблема заключается в том, что иногда сценарий зависает при возобновлении сна, поэтому вам может потребоваться перезагрузить его, что раздражает.

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

Это скрипт для замены клавиш CTRL и CAPS LOCK:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,00,3a,00,3a,00,1d,00,00,00,00,00

Если по какой-то причине вы не хотите запускать сторонние инструменты, возможно сделать это самостоятельно с небольшим количеством C. Благодаря блестящему ответу Сусама Пала я собрал фрагмент кода ниже.

Это практически клавиатурный шпион. Он прослушивает нажатия клавиш, фиксирует их и создает ввод с клавиатуры с учетом соответствия. Для работы должно быть запущено нижеприведенное консольное приложение.

Вам нужно будет как-то скомпилировать это. Я использовал msys2.org с pacman -S mingw-w64-x86_64-gcc и составлено с /mingw64/bin/gcc nocaps.c -o nocaps.exe,

#include <stdio.h>
#include <windows.h>

HHOOK hook;

#define KEYCODE_CAPSLOCK 20
#define KEYCODE_LCTRL 162

LRESULT CALLBACK keyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *) lParam;
    INPUT input = {.type = INPUT_KEYBOARD };

    printf("nCode=%d\t wParam=%d\t p->vkCode=%lu \t p->scanCode=%d\t\n", nCode, wParam, p->vkCode, p->scanCode);


    if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
        input.ki.dwFlags = KEYEVENTF_KEYUP;
    }

    if (p->vkCode == KEYCODE_CAPSLOCK && (p->flags & LLKHF_INJECTED) == 0) {
        input.ki.wVk = KEYCODE_LCTRL;
        SendInput(1, &input, sizeof (INPUT));
        return 1;
    } else if (p->vkCode == KEYCODE_LCTRL && (p->flags & LLKHF_INJECTED) == 0) {
        input.ki.wVk = KEYCODE_CAPSLOCK;
        SendInput(1, &input, sizeof (INPUT));
        return 1;
    }

    return CallNextHookEx(hook, nCode, wParam, lParam);
}

int main(int argc, char **argv)
{
    MSG messages;

    hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHook, NULL, 0);
    if (hook == NULL) {
        printf("Error %d\n", GetLastError());
        return 1;
    }

    printf("Mapping CAPSLOCK=>LCTRL and LCTRL=>CAPSLOCK..\n");
    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return 0;
}

Вы можете использовать lswitch для переназначения ввода языка в CapsLock.

Используйте любую клавишу для переключения языков ввода, использование: lswitch [keycode], Код ключа не является обязательным и по умолчанию используется ключ контекстного меню. Другим хорошим кандидатом является ключ CapsLock с кодом ключа 20.

lswitch 20

Добавьте его в автозагрузку.

Я собрал командный файл cmd,install-keyboard.bat(последняя версия в https://gitlab.com/0mid/dotfiles/-/blob/master/install-keyboard.bat ), чтобы сопоставить CapsLock и правую «клавишу Windows» с левым Ctrl (LCtrl).

Будем надеяться, что имена переменных для кодов клавиш и поясняющие комментарии (включая комментарии из @mnemotronic здесь и «официальной» документации в дополнение к моей) сделают этот сценарий полезным (и расширяемым) для тех, кто вынужден использовать эту проприетарную операционную систему. система (Виндовс).

Этот пакетный файл необходимо запустить в командной строке администратора, а для того, чтобы новые сопоставления вступили в силу , необходим выход из системы (НЕ перезапуск) . Кажется, не существует эквивалентного ключа для каждого пользователя (HKCU), поэтому это сопоставление влияет на всю локальную машину (HKLM).

Мне приходится это делать, потому что AutoHotKey работает ненадежно (в остальном это отличное бесплатное программное обеспечение, https://www.gnu.org/philosophy/free-sw.html, и для его «установки» не требуется администратор). использовать или вступить в силу). В частности, хотя в AutoHotKey я сопоставил «клавишу Windows» с Ctrl, Windows+d (ожидается, что это будет Ctrl-d) вместо этого продолжает сначала «перехватываться» Windows, вызывая отображение нескольких рабочих столов (что я мог бы не могу найти способ отключить) или, что еще хуже, произойдет неработающая клавиатура, в которой большинство клавиш даже не будут работать.

      @echo off
setlocal

net session >nul 2>&1 || (echo This script requires Admin.&goto :eof)

rem Unfortunately, as the key "Keyboard Layout" HAS TO be written
rem under HKEY_LOCAL_MACHINE\..., this needs Admin.

rem Also unfortunately, as the mappings are apparently read by the
rem keyboard driver at session start-up, once the mapping is stored in
rem the registry, a log out/log in was needed for the mapping to take
rem effect. Restarting explorer.exe did NOT do it. Microsoft docs
rem below says a restart is needed, which wasn't.

rem From
rem https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers#scan-code-mapper-for-keyboards:

rem ---

rem Windows 2000 and Windows XP include a new Scan Code Mapper, which
rem provides a method that allows for mapping of scan codes. The scan
rem code mappings for Windows are stored in the following registry
rem key: syntax

rem HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

rem Note There is also a Keyboard Layouts key (notice the plural form)
rem under the Control key, but that key should not be modified.

rem In the Keyboard Layout key, the Scancode Map value must be added.
rem This value is of type REG_BINARY (little Endian format) and has
rem the data format specified in the following table.

rem |Start offset (in bytes) | Size (in bytes) | Data                         |
rem |0                       |               4 | Header: Version Information  |
rem |4                       |               4 | Header: Flags                |
rem |8                       |               4 | Header: Number of Mappings   |
rem |12                      |               4 | Individual Mapping           |
rem |...                     |             ... | ...                          |
rem |Last 4 bytes            |               4 | Null Terminator (0x00000000) |

rem The first and second DWORDS store header information and should be
rem set to all zeroes for the current version of the Scan Code Mapper.
rem The third DWORD entry holds a count of the total number of
rem mappings that follow, including the null terminating mapping. The
rem minimum count would therefore be 1 (no mappings specified). The
rem individual mappings follow the header. Each mapping is one DWORD
rem in length and is divided into two WORD length fields. Each WORD
rem field stores the scan code for a key to be mapped.

rem Note that if the mapping of a scan code is necessary on a
rem keypress, the step is performed in user mode just before the scan
rem code is converted to a virtual key. Doing this conversion in user
rem mode can present certain limitations, such as mapping not working
rem correctly when running under Terminal Services.

rem To remove these mappings, remove the Scancode Map registry value
rem and reboot.

rem ---

rem The hex data is in five groups of four bytes:
rem   00,00,00,00,\    header version (always 00000000)
rem   00,00,00,00,\    header flags (always 00000000)
rem   03,00,00,00,\    # of entries (2 in this case) plus a NULL terminator line.
rem                    Entries are in 2-byte pairs: Key code to send & keyboard key to send it.
rem                    Each entry is in "least significant byte, most significant byte" order,
rem                    e.g. 0x1234 becomes `34,12`
rem   1d,00,3a,00,\    Send LEFT CTRL (0x001d) code when user presses the CAPS LOCK key (0x003a)
rem   1d,00,5c,e0,\    Send LEFT CTRL (0x001d) code when user presses the right Windows key (0xe05c)
rem   00,00,00,00      NULL terminator

set "CapsLock=3a,00"
set "LCtrl=1d,00"
set "RCtrl=1d,e0"
set "LAlt=38,00"
set "RAlt=38,e0"
set "LWin=5b,e0"
set "RWin=5c,e0"
set "Menu=5d,e0"

set "headerVersion=00,00,00,00"
set "headerFlags=00,00,00,00"
set "numEntries=03,00,00,00"
set "mapping1=%LCtrl%,%CapsLock%"
set "mapping2=%LCtrl%,%RWin%"
set "nullTerminator=00,00,00,00"
set "data=%headerVersion%%headerFlags%%numEntries%%mapping1%%mapping2%%nullTerminator%"
set "dataNoComma=%data:,=%"

set "key=HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layout"
reg add "%key%" /f /v "Scancode Map" /t REG_BINARY /d %dataNoComma%

echo Sign out and sign in for the new key mappings to take effect.

Я хотел бы поделиться своим решением AutoHotKey для Windows 10:

      Loop, %0%  ; For each parameter:
  {
    param := %A_Index%  ; Fetch the contents of the variable whose name is contained in A_Index.
    params .= A_Space . param
  }
ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA"

if not A_IsAdmin
{
    If A_IsCompiled
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1)
    Else
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1)
    ExitApp
}

+Capslock::Capslock ; make shift+Caps-Lock the Caps Lock toggle
Capslock::Control   ; make Caps Lock the control button
Другие вопросы по тегам