在Windows 7上将大写锁定映射为转义和控制


23

我希望能够将Caps Lock键映射为Escape(如果未使用任何其他键将其映射),而将其映射为Control。我该如何在Windows 7上做到这一点?



4
好吧,有条件的重新分配不在此处涵盖
wizzard0 2012年

我是通过修改寄存器来实现的:commons.lbl.gov/display/~jwelcher@lbl.gov/… 您需要在执行此操作后重新启动计算机。Win7的。
staticor

Answers:


8

您可以使用SharpKeys将其重新映射到Escape

但是,除了编写键盘驱动程序之外,我不知道执行条件重映射的实际方法。


1
我已经将我的Caps Lock键映射到带有SharpKeys的Escape。
Zameer Manji 2012年

6

这并不是您真正想要的,但是如果您可以忍受一些缺陷的话,那就非常接近了。这是一个AutoHotKey脚本:

$CapsLock::LControl
$CapsLock Up::Send {Escape}
return

释放键时,它将Caps Lock重新映射为Ctrl,并发送Escape。每当我放开Caps Lock键时,我都花了一段时间才能习惯按下Escape键。但是,这对网站文本区域几乎没有用处,因为按Escape键将失去对文本区域的关注。

我正在寻找解决方案。如果需要的话,我可能会用C语言编写某种驱动程序/键盘钩子,哈哈。

特定于Vim的烦恼:它使使用Ctrl-K组合键无法键入有向图,并且在习惯之前通常很烦人。不过,它对我来说效果很好,因为我会尽一切努力避免Esc和Ctrl键。


如果您只是想将其映射为转义,可以将其简化为:$CapsLock::Escape,然后立即return
Kazark

我试图理解-脚本的缺陷在于,当按下并释放Caps Lock时,会同时发送Ctrl和Escape吗?
Rishi

5

在上面Rich的解决方案之后,这可能已经出现在先前提到的vim wikia页面上。

; Author: fwompner gmail com
#InstallKeybdHook
SetCapsLockState, alwaysoff
Capslock::
Send {LControl Down}
KeyWait, CapsLock
Send {LControl Up}
if ( A_PriorKey = "CapsLock" )
{
    Send {Esc}
}
return

这不是我的工作,但是我已经开始使用它了,它的工作方式与描述的完全一样,没有真正的警告,并且由于它不尝试映射任何异常(因为它们是不必要的),因此在Chrome中的表现非常好(我真的想要用于Vimium)。


我一直在使用此脚本,它对我有用。我正在使用它来将Caps Lock重新绑定到vim的Control / Escape。
布兰登

1
作品!只是为了澄清,这是一个AutoHotKey脚本。从这里开始:autohotkey.com
迈克尔·福克斯

为了使未曾点击过并看到我的要旨的读者受益,看来该解决方案仅在按Caps Lock之前按才有效ShiftCaps+Shift+X有效,但Shift+Caps+X无效。
Rich

4

为此,我使用以下AutoHotkey脚本,该脚本改编自在Vim Tips Wiki上找到的脚本。该实现有点笨拙,但“对我有用”。(与截至2016-09-19的此页面上的其他答案不同,它完全解决了该问题,而我没有意识到任何警告。)

原始编码器指出:

该脚本还会尝试检测并避免“误报”,在这种情况下,您按Control键和另一个键并过快地释放它们(即,在超时期限之前)。

请务必根据您的键盘的好坏以及您自己的反应时间来调整250ms的值。这可能是您可以根据自己的喜好对实验进行调整的内容。

CapsLockCtrlEscape.ahk要点

g_LastCtrlKeyDownTime := 0
g_AbortSendEsc := false
g_ControlRepeatDetected := false

*CapsLock::
    if (g_ControlRepeatDetected)
    {
        return
    }

    send,{Ctrl down}
    g_LastCtrlKeyDownTime := A_TickCount
    g_AbortSendEsc := false
    g_ControlRepeatDetected := true

    return

*CapsLock Up::
    send,{Ctrl up}
    g_ControlRepeatDetected := false
    if (g_AbortSendEsc)
    {
        return
    }
    current_time := A_TickCount
    time_elapsed := current_time - g_LastCtrlKeyDownTime
    if (time_elapsed <= 250)
    {
        SendInput {Esc}
    }
    return

~*^a::
~*^b::
~*^c::
~*^d::
~*^e::
~*^f::
~*^g::
~*^h::
~*^i::
~*^j::
~*^k::
~*^l::
~*^m::
~*^n::
~*^o::
~*^p::
~*^q::
~*^r::
~*^s::
~*^t::
~*^u::
~*^v::
~*^w::
~*^x::
~*^y::
~*^z::
~*^1::
~*^2::
~*^3::
~*^4::
~*^5::
~*^6::
~*^7::
~*^8::
~*^9::
~*^0::
~*^Space::
~*^Backspace::
~*^Delete::
~*^Insert::
~*^Home::
~*^End::
~*^PgUp::
~*^PgDn::
~*^Tab::
~*^Return::
~*^,::
~*^.::
~*^/::
~*^;::
~*^'::
~*^[::
~*^]::
~*^\::
~*^-::
~*^=::
~*^`::
~*^F1::
~*^F2::
~*^F3::
~*^F4::
~*^F5::
~*^F6::
~*^F7::
~*^F8::
~*^F9::
~*^F10::
~*^F11::
~*^F12::
    g_AbortSendEsc := true
    return

3

这是一个注册表项,将大写锁定映射为在Windows 7上转义。


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,3a,00,46,00,01,00,3a,00,00,00,00,00

将以上内容保存到扩展名为.reg的文件(如mapCapLocks.reg),然后在您的计算机上导入/执行。


请在参考链接中引用答案的关键部分,因为如果链接页面发生更改,答案可能会失效。当前为404,因此此答案无用。
DavidPostill

优点。我将更新答案
Stryker

这还将ScrollLock键映射到CapsLock。如果这不是您想要的,请使用value hex:00,00,00,00,00,00,00,00,02,00,00,00,01,00,3a,00,00,00,00,00。该地图的有用编辑器是PlexData的ScancodeMapping
Appleshell

2

实际上,我认为我已经在这里构建了完美的解决方案:

作为Vim用户,这对我来说是必须的,并且我已经在Windows上成功使用了很长时间了。我只是在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Runregedit 上创建一个条目以指向可执行文件,并且它可以正常工作。

要编译和安装依赖项,请检查知识库自述文件和主网站以进行拦截。

我还在这里创建了相同版本的Linux版本:


2

我一直在寻找与此类似的内容,但不幸的是,此处答案中的AHK脚本对我而言效果不佳。

但是,我在vim wiki上找到了可以解决此问题的解决方案。

  • 首先,下载以下名为dual-key-remap的应用程序。
  • 将zip文件解压缩到您选择的位置(我将类似的实用程序存储在中C:\Users\%username%\util\
  • 打开以下目录:C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\按住ALT键创建快捷方式,然后将dual-key-remap.exe文件拖到此处。(或右键单击并选择“创建快捷方式”,然后将快捷方式移至启动目录)。
  • 登录和注销。登录后几秒钟,按键将反弹。


0

我没有足够的声誉来评论对我有用的答案。我仍然支持它。

Pepper-chico的回答对我有用

如果单独按下Caps Lock键,则其行为与Escape键相同。如果与其他键组合使用,则其行为类似于Ctrl键。我也有相同的用例。Vim。

他提供的链接中的说明很容易遵循。


0

如果您不介意自己编写简短的源代码,则可以使用下面的代码。您需要将其编译为Windows控制台应用程序。例如,在Visual C ++命令提示符下,您可以使用

cl /D_WIN32_WINNT=0x0401 remap_capslock.cpp /EHsc /link user32.lib

密钥重新映射在应用程序运行时起作用。无需重新启动,注销/登录等。如果需要重新映射才能以管理员身份运行的应用程序正常工作,则还需要以管理员身份运行重新映射器应用程序。到目前为止已经使用了几天(在Windows 10上),到目前为止还不错。

// The app allows to remap CapsLock key to Esc (if pressed separately) or to Ctrl (if pressed with other keys).
// This may be useful for Vim.
// To compile from Visual C++ command prompt: 
//    cl /D_WIN32_WINNT=0x0401 remap_capslock.cpp /EHsc /link user32.lib
// Original source (which supported only Caps-Ctrl remapping): /superuser//a/1490007/22750

#include <windows.h>
#include <iostream>
#include <set>

HHOOK hook;
std::set<WORD> keys_down;
bool caps_down = false;
bool caps_was_down_with_another_key = false;

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

    if ((p->flags & LLKHF_INJECTED) == 0) {
        std::cout << "nCode=" << nCode << "\twParam=" << wParam << "\tvkCode=" << p->vkCode << "\tscanCode=" << p->scanCode << std::endl;
        bool keyup = wParam == WM_KEYUP || wParam == WM_SYSKEYUP;
        if (p->vkCode == VK_CAPITAL) {
            if (keyup) {
                if (caps_was_down_with_another_key) {
                    std::cout << "Remapping CAPSLOCK UP to CTRL UP" << std::endl;
                    input[0].ki.dwFlags = KEYEVENTF_KEYUP;
                    input[0].ki.wVk = VK_LCONTROL;
                    SendInput(1, input, sizeof (INPUT));
                } else {
                    std::cout << "Remapping CAPSLOCK UP to ESCAPE DOWN&UP" << std::endl;
                    input[0].ki.dwFlags = KEYEVENTF_KEYUP;
                    input[0].ki.wVk = VK_LCONTROL;
                    input[1].ki.dwFlags = 0;
                    input[1].ki.wVk = VK_ESCAPE;
                    input[2].ki.dwFlags = KEYEVENTF_KEYUP;
                    input[2].ki.wVk = VK_ESCAPE;
                    SendInput(3, input, sizeof (INPUT));
                }
                caps_down = false;
                caps_was_down_with_another_key = false;
            } else {
                std::cout << "Remapping CAPSLOCK DOWN to CTRL DOWN" << std::endl;
                caps_down = true;
                input[0].ki.dwFlags = 0;
                input[0].ki.wVk = VK_LCONTROL;
                SendInput(1, input, sizeof (INPUT));
            }
            return 1;
        } else {
            if (keyup) {
                keys_down.erase(p->vkCode);
            } else {
                keys_down.insert(p->vkCode);
            }
            std::cout << keys_down.size() << " keys down" << std::endl;
        }
        if (caps_down && !keys_down.empty()) {
            caps_was_down_with_another_key = true;
        }
    }
    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) {
        std::cout << "Error " << GetLastError() << std::endl;
        return 1;
    }
    std::cout << "Mapping ??? CAPSLOCK=>LCTRL and LCTRL=>CAPSLOCK..." << std::endl;
    while (GetMessage (&messages, NULL, 0, 0)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return 0;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.