具体的代码可以到我的代码仓库找 https://github.com/mudssky/myAHKScripts
自动切换输入法,个人的需求主要是,在不需要或者很少需要中文输入的环境,比如说vscode,windows,terminal。这样工作体验就会更加顺滑。(我之前使用rime输入法就支持配置这个操作)
实现自动切换输入法,需要以下几点的前置储备
- 识别现在所处的输入法 ,需要调用windows api
- 切换现在所处的输入法,可以使用热键完成,也可以调用windows api
- 监控窗口的切换,切换到指定窗口时,执行操作
个人对windows api不是很熟悉,因此查了各种文档,最后还是从别人现成的实现里试着来修改。
因为以前的人用的都是老版本v1的语法,加上他们也没有什么函数命名的概念,给我的感觉就是很难读懂。
下面我的版本使用了v2的语法,并且把那些api都封装好了,相当于开箱即用了。
dllcall就可以用来调用windows api
window group适合用于批量监视窗口。
另外如果你想编写ahk的脚本的话,官方提供的windows spy脚本还是挺好用的。可以看到窗体的各种信息,方便你针对窗口编写程序。
但是因为我用的是v2版本,每次要用只能切到对应目录,拖到v1的执行程序上执行。
注意win10自带了给不同应用窗口使用不同输入法的功能。我的这个脚本最好配合开启win10自带的功能一起使用
win10自带的功能不足以满足需求的原因是,它貌似只会记录活动窗体的输入法状态,但是你把窗体关闭再重启后,就又是默认输入法了。
也许你把默认输入法设置为英文,再加上windows自带的功能就能满足一部分需求了。
/*
windows自带输入法的id,可以通过调用windows api GetKeyboardLayout来获取
微软拼音输入法 134481924
微软日文输入法 68224017
微软英文输入法 67699721
*/
IMEmap:=Map(
"zh",134481924,
"jp",68224017,
"en",67699721
)
; enAppList :=[
; "pwsh.exe"
; ]
; 获取当前激活窗口所使用的IME的ID
getCurrentIMEID(){
winID:=winGetID("A")
ThreadID:=DllCall("GetWindowThreadProcessId", "UInt", WinID, "UInt", 0)
InputLocaleID:=DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
return InputLocaleID
}
; 使用IMEID激活对应的输入法
switchIMEbyID(IMEID){
winTitle:=WinGetTitle("A")
PostMessage(0x50, 0, IMEID,, WinTitle )
}
; 切换微软拼音输入法
CapsLock & 1::{
switchIMEbyID(IMEmap["zh"])
; SetCapsLockState "alwaysoff"
}
; 切换微软英文键盘
CapsLock & 2::{
switchIMEbyID(IMEmap["en"])
; SetCapsLockState "alwaysoff"
}
; 切换微软日文输入法
CapsLock & 3::{
switchIMEbyID(IMEmap["jp"])
; SetCapsLockState "alwaysoff"
}
; 使用窗口组实现批量窗口的监视
GroupAdd "enAppGroup", "ahk_exe pwsh.exe" ;添加powershell
GroupAdd "enAppGroup", "ahk_exe Code.exe" ;添加 vscode
GroupAdd "enAppGroup", "ahk_exe WindowsTerminal.exe" ;添加windows terminal
; 循环等待知道窗口组的窗口激活,切换当前输入法为en,之后再等待当切换出当前窗口继续监视
Loop{
WinWaitActive "ahk_group enAppGroup"
currentWinID:= WinGetID("A")
; TrayTip Format("当前是{1},切换为en输入法", WinGetTitle("A"))
switchIMEbyID(IMEmap["en"])
; 从当且窗口切出,进行下一轮监视
WinWaitNotActive(currentWinID)
}
方法二 识别微软拼音的中英文模式
评论区有人提供了查询输入法中英文状态的api,那么只要检测状态,然后用Shift进行切换就可以了。比我之前切换输入法要方便一些。
; 设置脚本是否可以 "看见" 隐藏的窗口
DetectHiddenWindows True
; 可以用于判断微软拼音是否是英文模式
isEnglishMode(){
hWnd := winGetID("A")
result := SendMessage(
0x283, ; Message : WM_IME_CONTROL
0x001, ; wParam : IMC_GETCONVERSIONMODE
0, ; lParam : (NoArgs)
, ; Control : (Window)
; 获取当前输入法的模式
; Retrieves the default window handle to the IME class.
"ahk_id " DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", hWnd, "Uint")
)
; DetectHiddenWindows Fasle
; 返回值是0表示是英文模式,其他值表明是中文模式
return result == 0
}
然后我们只需要在进入enapp group的时候进行一次判断,调成英文模式
在离开enapp group的时候再进行一次判断调回中文模式。。。
用send 发送Shift键进行切换。
send "{Shift}"
我在代码仓库里已经更新了这个代码 https://github.com/mudssky/myAHKScripts