如何把 Windows 的大写锁定改为语言切换?
我最近开始用 Windows,由于前面两三年都是 Mac,现在用Win 的感觉非常难受,主要是键盘布局。
前面是序言,关于修改方法可以直接跳转到正文
Win 和 Mac 键盘布局最大的差异是对语言切换的理解。
我不知道Win究竟是出于什么思想,“竟然” 单独给大小写切换功能单独设置了一个按键,是遗产吗?或者是出某种来自远古的记忆?
我真的很好奇。
Mac 上通过 中/英 按键切换,但是 Windows 使用 shift 或者 Ctrl 切换语言。
两种截然不同的操作方式带来的迁移的成本很高,对与更改键盘布局的想法不是一天两天了。
先列一下各自的定义:
WIN
CapsLock:单击=锁定大写,长按=无;Shift/Ctrl/Ctrl-空格:单击=切换语言,长按=当前大写
MAC
中/英:单击=切换语言,长按=锁定大写Shift:单击=无,长按=当前大写
我最开始把通过设置把 Shift 改成:长按大写,单击切换语言。但是发现有些时候我会误触,把 CapsLock 当作 Shift,其实我也不知到是我误触还是键盘反应慢,总之就是我希望切换语言的时候,语言没有被更改。
然后又尝试通过修改注册表,把 CapsLock 映射 Ctrl,这种方式比较奇怪,因为注册表不能映射组合键,还是丢失了一个键。如果是键盘坏了,这样映射还行。另外,注册表只能处理点击,因为注册表不能判断是长按还是点击。
后来我不得不寻求更合适的方法,帮助我更优雅地从 Mac 过度到 Win,最终我通过 AutoHotkey 实现了。
正文
安装 AutoHotkey: https://autohotkey.com/download/ahk-v2.exe
注意,我使用的是 2.0 版本
创建文件 keyboard.ahk 文件,文件名称任意
这个文件是案例,不是最终的,最终的版本在下方
; 禁用原生 CapsLock 功能
SetCapsLockState("AlwaysOff")
; 全局变量保存 CapsLock 状态
CapsLockState := false
CapsLock::{
; 等待按键释放,超时时间 0.45 秒
result := KeyWait("CapsLock", "T0.45")
if (!result) {
; 长按:切换大小写锁定
global CapsLockState
CapsLockState := !CapsLockState
SetCapsLockState(CapsLockState ? "On" : "Off")
; 显示状态提示
ToolTip("CapsLock: " . (CapsLockState ? "ON" : "OFF"))
SetTimer(() => ToolTip(), -1000)
; 等待按键完全释放
KeyWait("CapsLock")
} else {
; 短按:切换输入法
Send("^{Space}")
}
}
然后双击这个文件就可以了,会出现一个对话框,只要不是报错就表示这个文件已经被配置了。
这个配置可以实现类似于 Mac 的输入方式:
将 CapsLock 改为语言切换
将 Shift 改为当前大写,长按没有功能。
实际上最重要的就是这一句:
CapsLock::{
Send("^{Space}")
}
将 CapsLock 键映射为 Ctrl-空格,其他都是在处理长按和短按的逻辑而已。
但是,上面的代码有一个问题:如果当前是大写的时候更改语言后还是大写。
另外,我希望代码逻辑更偏向于函数式,这样比较一目了然;我希望有声音提示和工具提示,因为大多数时候我都是在用 Vim,不希望有任何不必要的动作打断我操作的连贯性。
于是就有了下面的代码:
; 禁用原生 CapsLock 功能
SetCapsLockState("AlwaysOff")
; 全局变量保存 CapsLock 状态
CapsLockState := false
CapsLock::{
; 第一步:判断是长按还是短按
; 等待按键释放,超时时间 0.45 秒
isShortPress := KeyWait("CapsLock", "T0.45")
; 第二步:根据按键类型执行对应逻辑
if (isShortPress) {
; ===== 短按逻辑 =====
HandleShortPress()
} else {
; ===== 长按逻辑 =====
HandleLongPress()
; 等待按键完全释放
KeyWait("CapsLock")
}
}
; 短按处理函数:切换输入法
HandleShortPress() {
; 切换输入法
Send("^{Space}")
SetCapsLockState("Off")
; 稍等一下让切换生效
Sleep(100)
; 获取切换后的状态
SetTimer(() => ToolTip(), -1200)
; 提示音
SoundBeep(600, 80) ; 中文输入法
}
; 长按处理函数:切换大小写锁定
HandleLongPress() {
global CapsLockState
if (CapsLockState) {
; 当前开启 → 关闭
CapsLockState := false
SetCapsLockState("Off")
; ToolTip("🔓 CapsLock: OFF (小写模式)`n" . langInfo)
ToolTip("🔓 CapsLock: OFF (小写模式)`n")
SoundBeep(400, 100) ; 低音表示关闭
} else {
; 当前关闭 → 开启
CapsLockState := true
SetCapsLockState("On")
; ToolTip("🔒 CapsLock: ON (大写模式)`n" . langInfo)
ToolTip("🔒 CapsLock: ON (大写模式)`n")
SoundBeep(800, 100) ; 高音表示开启
}
; 1.5秒后清除提示
SetTimer(() => ToolTip(), -1500)
}
; 获取CapsLock状态显示
GetCapsLockStatus() {
if (GetKeyState("CapsLock", "T")) {
return "🔒 大写锁定: 开启"
} else {
return "🔓 大写锁定: 关闭"
}
}
; 添加启动时显示当前状态的快捷键 (Ctrl+CapsLock)
^CapsLock::{
capsStatus := GetCapsLockStatus()
ToolTip("📊 当前状态`n" . capsStatus . "`n`n💡 提示:`n• 短按CapsLock: 切换输入法`n• 长按CapsLock: 切换大小写`n• Ctrl+CapsLock: 显示此状态")
SetTimer(() => ToolTip(), -3000)
}
好了,现在这个代码基本就是我觉得比较好用的了:
- 语言切换时有声音提示和工具提示
CapsLock的设置- 英文模式下:
- 长按是大写锁定,再次长按是小写
- 点击是切换语言
- 中文模式下:
- 长按是大写锁定,再次长按是中文
- 点击是切换语言
- 英文模式下:
Ctrl-CapsLock是工具提示,我准备加一下 vim 的东西,这里就不写了。

浙公网安备 33010602011771号