autohotkey v2 实现自动切换输入法,添加输入法切换快捷键

具体的代码可以到我的代码仓库找 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