用WM_INPUTLANGCHANGEREQUEST消息修改窗口的输入法,在资源管理器上总是会被自动恢复成 ENG
我在用 AHK v2 来使用 SendMessage 来调用 WM_INPUTLANGCHANGEREQUEST 的,我也不是很能确定是不是 WM_INPUTLANGCHANGEREQUEST 本身的问题,还是 AHK 在 SendMessage 上有问题。我在其他语言中(如c++和c#),尚未掌握 hook 键盘快捷键以及使它在后台调用 WindowsApi 的写法,所以我没有能力做这个测试,如果可以的话请大家帮帮忙。内容很简单:
#Requires AutoHotkey v2.0
; Change to Next Language Layout on ImmGetDefualtIMEWnd of current actived window
~LCtrl:: {
WM_INPUTLANGCHANGEREQUEST := 0x50
INPUTLANGCHANGE_FORWARD := 0x0002
ActivedhWnd := WinGetID("A") ; Get the actived Window's hWnd
SendMessage(WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_FORWARD, , , DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", ActivedhWnd), 1000)
}
代码很简单,就是按下左 Ctrl 时调用 SendMessage ,对当前激活的窗口的 IMEWnd 发送 WM_INPUTLANGCHANGEREQUEST 消息,使键盘布局切换到下一个,这样就能切换到其他语言的输入法了。
这在其他窗口测试都没有问题,唯独在 windows 资源管理器中出现了意料之外的情况:无论之前是在哪个调用 WM_INPUTLANGCHANGEREQUEST 修改了输入法,当我再次激活资源管理器时,一定会切回英文。 我保证键盘设置中的『允许我为每个应用窗口使用不同的输入法』是关闭的,所以应该没有其他任何东西在修改输入法,输入法不应该在切换窗口的时候被修改。但事实就是打开资源管理器就会自动切换回英文。
上面的描述是在使用 WM_INPUTLANGCHANGEREQUEST 来修改输入法的情况下出现的,作为对照,我也用系统内置的 Win+Space 切换输入法来做了一个对照实验,结果是这样切换的输入法,在切换到资源管理器的时候,正常地保留下来了,并没有被切换回 ENG 。
所以可以证明,问题出于代码上,但是我不能确定是不是 WM_INPUTLANGCHANGEREQUEST 的问题。还是有什么我错漏的地方,导致切换的输入法会被资源管理器恢复吗?还是说同样的实现方式,在其他语言里都不能复现此问题,纯粹是 AHK 的问题?